kee

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

commit 4cdeee84bb44871f1936e0fb3c25ed3aca996fbd
parent 5a1d336d2205561a61cc9e2e556bfe0cdeb2f018
Author: lash <dev@holbrook.no>
Date:   Wed, 24 Apr 2024 16:08:28 +0100

Add display mode switch for kee entry

Diffstat:
Msrc/gtk/kee-entry-item-store.c | 1-
Msrc/gtk/kee-entry-list.c | 7+++----
Msrc/gtk/kee-entry-store.c | 2+-
Msrc/gtk/kee-entry.c | 108++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Msrc/gtk/kee-entry.h | 12+++++++++---
Msrc/gtk/kee-menu.c | 24+++++++++++++++++++-----
6 files changed, 109 insertions(+), 45 deletions(-)

diff --git a/src/gtk/kee-entry-item-store.c b/src/gtk/kee-entry-item-store.c @@ -82,7 +82,6 @@ KeeEntryItemStore* kee_entry_item_store_new(struct db_ctx *db, struct kee_ledger return o; } - /// \todo always scans from 0, inefficient /// \todo enum lookup states static int kee_entry_item_store_scan(KeeEntryItemStore *o) { diff --git a/src/gtk/kee-entry-list.c b/src/gtk/kee-entry-list.c @@ -18,18 +18,17 @@ struct _KeeEntryList { G_DEFINE_TYPE(KeeEntryList, kee_entry_list, GTK_TYPE_BOX); static void kee_entry_list_handle_select(GtkListView *view, guint i, KeeMenu *menu) { - GtkSingleSelection *sel; - KeeEntry *o; GtkWidget *widget; GtkWidget *container; + GtkSingleSelection *sel; + KeeEntry *o; sel = GTK_SINGLE_SELECTION(gtk_list_view_get_model(view)); o = KEE_ENTRY(gtk_single_selection_get_selected_item(sel)); g_object_take_ref(G_OBJECT(o)); - container = kee_menu_next(menu, "entry"); - if (!kee_entry_apply_display_widget(o)) { + if (kee_entry_modeswitch(o, KEE_ENTRY_VIEWMODE_FULL)) { widget = gtk_widget_get_first_child(container); if (widget) { gtk_box_remove(GTK_BOX(container), widget); diff --git a/src/gtk/kee-entry-store.c b/src/gtk/kee-entry-store.c @@ -76,7 +76,7 @@ static gpointer kee_entry_store_get_item(GListModel *list, guint index) { g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "entry index %d malformed", index); } - kee_entry_apply_list_item_widget(o); + kee_entry_modeswitch(o, KEE_ENTRY_VIEWMODE_SHORT); return o; } diff --git a/src/gtk/kee-entry.c b/src/gtk/kee-entry.c @@ -31,19 +31,25 @@ struct _KeeEntryClass { GtkWidget parent_class; }; +#define ENTRYSTATE_LOAD 1 +#define ENTRYSTATE_SHORT 2 +#define ENTRYSTATE_EDIT 4 + extern const asn1_static_node schema_entry_asn1_tab[]; /// \todo factor out separate struct for listitem struct _KeeEntry { GtkWidget parent; + GtkWidget *display; + GtkWidget *edit; GtkWidget *entry_list; + GtkWidget *showing; int state; char header[1024]; struct kee_dn_t bob_dn; char current_id[64]; struct kee_ledger_t ledger; struct Cadiz *resolver; - int is_displaying; struct db_ctx *db; }; @@ -90,13 +96,77 @@ static void kee_entry_class_init(KeeEntryClass *kls) { } static void kee_entry_init(KeeEntry *o) { - o->state = 2; + o->state = 0; o->resolver = NULL; - o->is_displaying = 0; + o->showing = NULL; + o->display = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);; kee_ledger_init(&o->ledger); kee_ledger_reset_cache(&o->ledger); } +static int kee_entry_apply_list_item_widget(KeeEntry *o) { + char mask; + + mask = ENTRYSTATE_LOAD; + if (!(o->state & mask)) { + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "entry must be loaded first"); + return -1; + } + mask |= ENTRYSTATE_SHORT; + if ((o->state & mask) == mask) { + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "entry already in short mode"); + return 0; + } + + sprintf(o->header, "%s [%s]\n%s (%s)\nalice: %d\nbob: %d", o->ledger.content.subject, o->ledger.uoa, o->bob_dn.cn, o->bob_dn.uid, o->ledger.cache->alice_credit_balance, o->ledger.cache->bob_credit_balance); + o->entry_list = gtk_label_new(o->header); + o->state |= ENTRYSTATE_SHORT; + o->state &= mask; + o->showing = o->entry_list; + return 1; +} + + +static int kee_entry_apply_display_widget(KeeEntry *o) { + char mask; + + mask = ENTRYSTATE_SHORT | ENTRYSTATE_EDIT; + if ((o->state & mask) == 0) { + return 0; + } + o->state &= ~mask; + o->showing = o->display; + return 1; +} + +static int kee_entry_apply_edit_widget(KeeEntry *o) { + o->edit = gtk_label_new("editing"); + o->showing = o->edit; + return 1; +} + +int kee_entry_modeswitch(KeeEntry *o, enum kee_entry_viewmode_e mode) { + int r; + + if (o->showing != NULL) { + gtk_widget_set_visible(o->showing, false); + gtk_box_remove(GTK_BOX(o), o->showing); + } + switch(mode) { + case KEE_ENTRY_VIEWMODE_SHORT: + r = kee_entry_apply_list_item_widget(o); + break; + case KEE_ENTRY_VIEWMODE_EDIT: + r = kee_entry_apply_edit_widget(o); + break; + default: + r = kee_entry_apply_display_widget(o); + } + gtk_box_append(GTK_BOX(o), o->showing); + gtk_widget_set_visible(o->showing, true); + return r; +} + KeeEntry* kee_entry_new(struct db_ctx *db) { KeeEntry *o; o = KEE_ENTRY(g_object_new(KEE_TYPE_ENTRY, "orientation", GTK_ORIENTATION_VERTICAL, NULL)); @@ -113,6 +183,7 @@ static void kee_entry_init_list_widget(KeeEntry *o) { GtkSingleSelection *sel; GtkListItemFactory *factory; KeeEntryItemStore *model; + GtkWidget *view; factory = gtk_signal_list_item_factory_new(); g_signal_connect(factory, "setup", G_CALLBACK(kee_entry_handle_item_setup), NULL); @@ -120,7 +191,8 @@ static void kee_entry_init_list_widget(KeeEntry *o) { model = kee_entry_item_store_new(o->db, &o->ledger, o->resolver); sel = gtk_single_selection_new(G_LIST_MODEL(model)); - o->entry_list = gtk_list_view_new(GTK_SELECTION_MODEL(sel), GTK_LIST_ITEM_FACTORY(factory)); + view = gtk_list_view_new(GTK_SELECTION_MODEL(sel), GTK_LIST_ITEM_FACTORY(factory)); + gtk_box_append(GTK_BOX(o->display), GTK_WIDGET(view)); } int kee_entry_deserialize(KeeEntry *o, const char *data, size_t data_len) { @@ -173,35 +245,9 @@ int kee_entry_deserialize(KeeEntry *o, const char *data, size_t data_len) { return ERR_DIGESTFAIL; } - o->state = 0; + o->state = ENTRYSTATE_LOAD; kee_entry_init_list_widget(o); return ERR_OK; } - -void kee_entry_apply_list_item_widget(KeeEntry *o) { - GtkWidget *widget; - - if (o->state) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "entry must be loaded first"); - return; - } - - sprintf(o->header, "%s [%s]\n%s (%s)\nalice: %d\nbob: %d", o->ledger.content.subject, o->ledger.uoa, o->bob_dn.cn, o->bob_dn.uid, o->ledger.cache->alice_credit_balance, o->ledger.cache->bob_credit_balance); - widget = gtk_label_new(o->header); - gtk_box_append(GTK_BOX(o), widget); - o->is_displaying = 0; - return; -} - - -int kee_entry_apply_display_widget(KeeEntry *o) { - if (o->is_displaying) { - return 1; - } - o->is_displaying = 1; - - gtk_box_append(GTK_BOX(o), o->entry_list); - return 0; -} diff --git a/src/gtk/kee-entry.h b/src/gtk/kee-entry.h @@ -21,17 +21,23 @@ enum KEE_ENTRY_SIGNS { BOB_COLLATERAL_NEGATIVE = 8, }; +enum kee_entry_viewmode_e { + KEE_ENTRY_VIEWMODE_SHORT, + KEE_ENTRY_VIEWMODE_FULL, + KEE_ENTRY_VIEWMODE_EDIT, +}; + #define KEE_TYPE_ENTRY kee_entry_get_type() 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 *data, size_t data_len); -void kee_entry_apply_list_item_widget(KeeEntry *o); -int kee_entry_apply_display_widget(KeeEntry *o); +//int kee_entry_apply_list_item_widget(KeeEntry *o); +//int kee_entry_apply_display_widget(KeeEntry *o); KeeEntry* kee_entry_new(struct db_ctx *db); void kee_entry_set_resolver(KeeEntry *o, struct Cadiz *resolver); +int kee_entry_modeswitch(KeeEntry *o, enum kee_entry_viewmode_e); G_END_DECLS - #endif //_GTK_KEE_ENTRY_H diff --git a/src/gtk/kee-menu.c b/src/gtk/kee-menu.c @@ -27,9 +27,15 @@ 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"); +static void kee_menu_act_import(GAction *act, GVariant *param, KeeMenu *menu) {//GtkStack *stack) { + //gtk_stack_set_visible_child_name(stack, "import"); + kee_menu_next(menu, "import"); +} + +static void kee_menu_act_new_entry(GAction *act, GVariant *param, KeeMenu *menu) {//GtkStack *stack) { + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "act new entry"); + //gtk_stack_set_visible_child_name(stack, "import"); + kee_menu_next(menu, "entry"); } //static GParamSpec *kee_props[KEE_N_MENU_PROPS] = {NULL,}; @@ -73,11 +79,19 @@ KeeMenu* kee_menu_new(GtkApplication *gapp) { act = g_simple_action_new("import", 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("insert-object"); gtk_header_bar_pack_start(GTK_HEADER_BAR(o->head), butt); gtk_actionable_set_action_name(GTK_ACTIONABLE(butt), "win.import"); - g_signal_connect(act, "activate", G_CALLBACK(kee_menu_act_import), o->stack); + g_signal_connect(act, "activate", G_CALLBACK(kee_menu_act_import), o); + + act = g_simple_action_new("new_entry", 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("document-new"); + gtk_header_bar_pack_start(GTK_HEADER_BAR(o->head), butt); + gtk_actionable_set_action_name(GTK_ACTIONABLE(butt), "win.new_entry"); + g_signal_connect(act, "activate", G_CALLBACK(kee_menu_act_new_entry), o); + gtk_window_set_titlebar(GTK_WINDOW(o), GTK_WIDGET(o->head));