kee

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

commit 50ffa4663f523dc2b35927273f6b770378934632
parent be26f8da0c2f5109d8b28084b9dfc046ef300515
Author: lash <dev@holbrook.no>
Date:   Thu, 21 Mar 2024 16:05:50 +0000

Add focus on text view after qr read

Diffstat:
Msrc/gtk/kee-import.c | 27++++++++++++++++++++++++---
Msrc/gtk/kee-import.h | 2++
Msrc/gtk/main.c | 1-
Msrc/gtk/ui.c | 98++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Msrc/gtk/ui.h | 9+++------
5 files changed, 111 insertions(+), 26 deletions(-)

diff --git a/src/gtk/kee-import.c b/src/gtk/kee-import.c @@ -19,6 +19,7 @@ struct _KeeImport { GListModel *camera_list; struct kee_camera_devices camera_device; struct kee_scanner scan; + GtkStack *stack; }; G_DEFINE_TYPE(KeeImport, kee_import, GTK_TYPE_BOX); @@ -39,12 +40,25 @@ static void kee_import_class_init(KeeImportClass *kls) { 0, NULL ); + + kee_sigs[KEE_S_IMPORT_DATA] = g_signal_new("data_available", + G_TYPE_FROM_CLASS(o), + G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_STRING + ); } static void kee_import_init(KeeImport *o) { o->camera_list = G_LIST_MODEL(g_list_store_new(GTK_TYPE_LABEL)); kee_import_refresh(o); memset(&o->scan, 0, sizeof(struct kee_scanner)); + o->stack = gtk_stack_new(); } static void kee_import_scanadd(KeeImport *o, GtkLabel *label) { @@ -77,7 +91,6 @@ int kee_import_refresh(KeeImport *o) { static void kee_import_apply_viewfinder(KeeImport *o) { GtkWidget *p; - GtkWidget *label; p = gtk_widget_get_first_child(GTK_WIDGET(o)); if (p) { @@ -98,11 +111,14 @@ static gboolean kee_import_scan_code_handler(GstBus *bus, GstMessage *msg, gpoin const gchar *src; const gchar *code; const GstStructure *strctr; + KeeImport *import; //struct _gst_data *data; //GstStateChangeReturn rsc; //data = (struct _gst_data*)user_data; + import = KEE_IMPORT(user_data); + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "scan msg got"); switch (GST_MESSAGE_TYPE (msg)) { @@ -128,9 +144,10 @@ static gboolean kee_import_scan_code_handler(GstBus *bus, GstMessage *msg, gpoin strctr = gst_message_get_structure(msg); code = gst_structure_get_string(strctr, "symbol"); g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "message %s: %d (%s) - decoded: %s", src, msg->type, gst_message_type_get_name(msg->type), code); - break; + g_signal_emit(import, kee_sigs[KEE_S_IMPORT_DATA], 0, code); + return false; default: - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "unknown message (ext %d): %s", GST_MESSAGE_TYPE_IS_EXTENDED(msg), GST_MESSAGE_TYPE_NAME(msg)); + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "unhandled message (ext %d): %s", GST_MESSAGE_TYPE_IS_EXTENDED(msg), GST_MESSAGE_TYPE_NAME(msg)); break; } @@ -164,3 +181,7 @@ void kee_import_free(KeeImport *o) { kee_camera_free(&o->camera_device); scan_free(&o->scan); } + +GtkStack* kee_import_get_stack(KeeImport *o) { + return o->stack; +} diff --git a/src/gtk/kee-import.h b/src/gtk/kee-import.h @@ -10,6 +10,7 @@ G_DECLARE_FINAL_TYPE(KeeImport, kee_import, KEE, IMPORT, GtkBox) enum KEE_IMPORT_SIGS { KEE_S_IMPORT_SCAN_CHANGE, + KEE_S_IMPORT_DATA, KEE_N_IMPORT_SIGS, }; @@ -17,6 +18,7 @@ KeeImport* kee_import_new(void); int kee_import_refresh(KeeImport *im); GListModel* kee_import_get_camera_list(KeeImport *o); int kee_import_scanchange(KeeImport *o, const char *device); +GtkStack* kee_import_get_stack(KeeImport *o); G_END_DECLS diff --git a/src/gtk/main.c b/src/gtk/main.c @@ -55,7 +55,6 @@ int main(int argc, char **argv) { g_signal_connect (gapp, "activate", G_CALLBACK (activate), uctx); g_signal_connect (gapp, "activate", G_CALLBACK (activate_scan), import); g_signal_connect (gapp, "shutdown", G_CALLBACK (deactivate), uctx); - g_signal_connect (uctx, "scan", G_CALLBACK( ui_handle_scan) , uctx); g_signal_connect (uctx, "unlock", G_CALLBACK(ui_handle_unlock), uctx); g_signal_connect (uctx, "state", G_CALLBACK(state_log), NULL); diff --git a/src/gtk/ui.c b/src/gtk/ui.c @@ -1,4 +1,5 @@ #include <string.h> + #include <gtk/gtk.h> #include <gst/gst.h> @@ -16,6 +17,24 @@ static void new_item(GtkListItemFactory *factory, GtkListItem *item, gpointer user_data) { } +void ui_handle_import_data_focus(KeeImport *o, const char *data, GtkStack *stack) { + gtk_stack_set_visible_child_name(stack, KEE_ACT_SCAN_TEXT); +} + +void ui_handle_import_data_text(KeeImport *o, const char *data, GtkTextBuffer *buf) { + gtk_text_buffer_set_text(buf, data, strlen(data)); + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "import data %s", data); +} + +void ui_handle_import_data_accept(KeeImport *o, const char *data, GActionMap *am) { + GAction *act; + + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "import accept %s", data); + + act = g_action_map_lookup_action(am, "import_data_accept"); + g_simple_action_set_enabled(G_SIMPLE_ACTION(act), true); +} + static void win_handle_state(KeeUicontext *uctx, char state_hint, kee_state_t *new_state, kee_state_t *old_state, GtkWindow *win) { GAction *act; @@ -35,13 +54,20 @@ static void act_import(GAction *act, GVariant *param, GtkStack *stack) { gtk_stack_set_visible_child_name(stack, "import"); } -static void act_scan_select(GActionGroup *act, GtkActionBar *foot) { + +//static void act_scan_select(GActionGroup *act, GtkActionBar *foot) { +// \todo why is there user_data in addition to pointer +static void act_scan_select(GActionGroup *act, char *action_name, gpointer user_data, GtkStack *stack) { GVariant *v; + const char *s; - v = g_action_group_get_action_state(act, "src"); - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "have act select: %d", g_variant_get_uint32(v)); + v = g_action_group_get_action_state(act, action_name); + s = g_variant_get_string(v, NULL); + //g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "have act select: %d", g_variant_get_string(v)); + gtk_stack_set_visible_child_name(stack, s); } + void ui_handle_unlock(KeeUicontext *uctx, gpointer user_data) { kee_state_t state_delta; @@ -119,7 +145,7 @@ static GtkWidget* ui_build_scan_videochooser(KeeImport *import) { } -static GtkWidget* ui_build_scan_footer(KeeImport *import) { +static GtkWidget* ui_build_scan_footer(KeeImport *import, GtkStack *stack) { GtkWidget *foot; GtkWidget *butt; GtkToggleButton *butt_prev; @@ -129,12 +155,12 @@ static GtkWidget* ui_build_scan_footer(KeeImport *import) { foot = gtk_action_bar_new(); - v = g_variant_new_uint32(0); + v = g_variant_new_string(""); ag = G_ACTION_GROUP(g_simple_action_group_new()); - act = G_ACTION(g_simple_action_new_stateful("src", G_VARIANT_TYPE_UINT32, v)); + act = G_ACTION(g_simple_action_new_stateful("src", G_VARIANT_TYPE_STRING, v)); g_action_map_add_action(G_ACTION_MAP(ag), act); - v = g_variant_new_uint32(KEE_ACT_SCAN_QR); + v = g_variant_new_string(KEE_ACT_SCAN_QR); butt = gtk_toggle_button_new(); gtk_button_set_icon_name(GTK_BUTTON(butt), "insert-image"); gtk_action_bar_pack_start(GTK_ACTION_BAR(foot), butt); @@ -143,7 +169,7 @@ static GtkWidget* ui_build_scan_footer(KeeImport *import) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(butt), true); butt_prev = GTK_TOGGLE_BUTTON(butt); - v = g_variant_new_uint32(KEE_ACT_SCAN_FILE); + v = g_variant_new_string(KEE_ACT_SCAN_TEXT); butt = gtk_toggle_button_new(); gtk_toggle_button_set_group(GTK_TOGGLE_BUTTON(butt), butt_prev); gtk_button_set_icon_name(GTK_BUTTON(butt), "document-new"); @@ -152,7 +178,7 @@ static GtkWidget* ui_build_scan_footer(KeeImport *import) { gtk_actionable_set_action_target_value(GTK_ACTIONABLE(butt), v); butt_prev = GTK_TOGGLE_BUTTON(butt); - v = g_variant_new_uint32(KEE_ACT_SCAN_TEXT); + v = g_variant_new_string(KEE_ACT_SCAN_FILE); butt = gtk_toggle_button_new(); gtk_toggle_button_set_group(GTK_TOGGLE_BUTTON(butt), butt_prev); gtk_button_set_icon_name(GTK_BUTTON(butt), "document-save"); @@ -160,20 +186,52 @@ static GtkWidget* ui_build_scan_footer(KeeImport *import) { gtk_actionable_set_action_name(GTK_ACTIONABLE(butt), "import.src"); gtk_actionable_set_action_target_value(GTK_ACTIONABLE(butt), v); - g_signal_connect(ag, "action-state-changed", G_CALLBACK(act_scan_select), ag); + g_signal_connect(ag, "action-state-changed", G_CALLBACK(act_scan_select), stack); gtk_widget_insert_action_group(foot, "import", ag); return foot; } + +static GtkWidget* ui_build_import_text(GtkApplication *app, KeeImport *import, GtkStack *stack) { + GtkWidget *box; + GtkTextView *txt; + GtkWidget *butt; + GAction *act; + + box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + + txt = GTK_TEXT_VIEW(gtk_text_view_new()); + gtk_widget_set_vexpand(GTK_WIDGET(txt), true); + gtk_box_append(GTK_BOX(box), GTK_WIDGET(txt)); + + act = G_ACTION(g_simple_action_new("import_data_accept", NULL)); + g_simple_action_set_enabled(G_SIMPLE_ACTION(act), false); + g_action_map_add_action(G_ACTION_MAP(app), act); + + butt = gtk_button_new_with_label("import"); + gtk_actionable_set_action_name(GTK_ACTIONABLE(butt), "app.import_data_accept"); + gtk_box_append(GTK_BOX(box), butt); + + g_signal_connect(import, "data_available", G_CALLBACK(ui_handle_import_data_text), gtk_text_view_get_buffer(txt)); + g_signal_connect(import, "data_available", G_CALLBACK(ui_handle_import_data_accept), app); // replace with import + g_signal_connect(import, "data_available", G_CALLBACK(ui_handle_import_data_focus), stack); + + return box; +} + + void ui_build_scan(GtkApplication *app, KeeImport *import) { GtkWidget *chooser; + GtkWidget *box_outer; GtkWidget *box; GtkWidget *widget; - GtkWidget *stack; + GtkStack *stack; - stack = gtk_stack_new(); + box_outer = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10); + + stack = kee_import_get_stack(import); box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10); @@ -182,11 +240,19 @@ void ui_build_scan(GtkApplication *app, KeeImport *import) { gtk_box_append(GTK_BOX(box), GTK_WIDGET(import)); - widget = ui_build_scan_footer(import); - gtk_box_append(GTK_BOX(box), widget); - gtk_stack_add_child(GTK_STACK(stack), box); + gtk_stack_add_named(stack, box, KEE_ACT_SCAN_QR); + + widget = ui_build_import_text(app, import, stack); + gtk_stack_add_named(stack, widget, KEE_ACT_SCAN_TEXT); + + gtk_stack_set_visible_child_name(stack, KEE_ACT_SCAN_QR); + + widget = ui_build_scan_footer(import, stack); + + gtk_box_append(GTK_BOX(box_outer), GTK_WIDGET(stack)); + gtk_box_append(GTK_BOX(box_outer), widget); - kee_view_add(stack, "import"); + kee_view_add(box_outer, "import"); } diff --git a/src/gtk/ui.h b/src/gtk/ui.h @@ -5,16 +5,13 @@ #include "kee-uicontext.h" #include "kee-import.h" -enum KeeActScan { - KEE_ACT_SCAN_QR = 1, - KEE_ACT_SCAN_FILE, - KEE_ACT_SCAN_TEXT -}; +#define KEE_ACT_SCAN_QR "import_scan" +#define KEE_ACT_SCAN_FILE "import_file" +#define KEE_ACT_SCAN_TEXT "import_text" void ui_build(GtkApplication *app, KeeUicontext *uctx); void ui_build_scan(GtkApplication *app, KeeImport *imp); -void ui_handle_scan(KeeUicontext *uctx); void ui_handle_unlock(KeeUicontext *uctx, gpointer user_data); #endif // _UI_H