35 #include <glib/gi18n.h> 36 #include <gwenhywfar/gui_be.h> 37 #include <gwenhywfar/inherit.h> 38 #include <gwenhywfar/version.h> 40 #include "dialog-utils.h" 42 #include "gnc-component-manager.h" 44 #include "gnc-session.h" 52 # define GNC_GWENHYWFAR_CB GWENHYWFAR_CB 54 #define GWEN_GUI_CM_CLASS "dialog-hbcilog" 55 #define GNC_PREFS_GROUP_CONNECTION GNC_PREFS_GROUP_AQBANKING ".connection-dialog" 56 #define GNC_PREF_CLOSE_ON_FINISH "close-on-finish" 57 #define GNC_PREF_REMEMBER_PIN "remember-pin" 59 # include <gwen-gui-gtk3/gtk3_gui.h> 65 static GncGWENGui *full_gui = NULL;
69 static GWEN_GUI *log_gwen_gui = NULL;
72 static GLogLevelFlags log_levels[] =
84 static guint8 n_log_levels = G_N_ELEMENTS(log_levels);
87 GWEN_INHERIT(GWEN_GUI, GncGWENGui)
88 #define SETDATA_GUI(gwen_gui, gui) GWEN_INHERIT_SETDATA(GWEN_GUI, GncGWENGui, \ 89 (gwen_gui), (gui), NULL) 90 #define GETDATA_GUI(gwen_gui) GWEN_INHERIT_GETDATA(GWEN_GUI, GncGWENGui, (gwen_gui)) 92 #define OTHER_ENTRIES_ROW_OFFSET 3 95 typedef enum _GuiState GuiState;
97 static void register_callbacks(GncGWENGui *gui);
98 static void unregister_callbacks(GncGWENGui *gui);
99 static void setup_dialog(GncGWENGui *gui);
100 static void enable_password_cache(GncGWENGui *gui, gboolean enabled);
101 static void reset_dialog(GncGWENGui *gui);
102 static void set_finished(GncGWENGui *gui);
103 static void set_aborted(GncGWENGui *gui);
104 static void show_dialog(GncGWENGui *gui, gboolean clear_log);
105 static void hide_dialog(GncGWENGui *gui);
106 static gboolean show_progress_cb(gpointer user_data);
107 static void show_progress(GncGWENGui *gui, Progress *progress);
108 static void hide_progress(GncGWENGui *gui, Progress *progress);
109 static void free_progress(Progress *progress, gpointer unused);
110 static gboolean keep_alive(GncGWENGui *gui);
111 static void cm_close_handler(gpointer user_data);
112 static void erase_password(gchar *password);
113 static gchar *strip_html(gchar *text);
114 static void get_input(GncGWENGui *gui, guint32 flags,
const gchar *title,
115 const gchar *text,
const char *mimeType,
116 const char *pChallenge, uint32_t lChallenge,
117 gchar **input, gint min_len, gint max_len);
118 static gint GNC_GWENHYWFAR_CB messagebox_cb(GWEN_GUI *gwen_gui, guint32 flags,
const gchar *title,
119 const gchar *text,
const gchar *b1,
const gchar *b2,
120 const gchar *b3, guint32 guiid);
121 static gint GNC_GWENHYWFAR_CB inputbox_cb(GWEN_GUI *gwen_gui, guint32 flags,
const gchar *title,
122 const gchar *text, gchar *buffer, gint min_len,
123 gint max_len, guint32 guiid);
124 static guint32 GNC_GWENHYWFAR_CB showbox_cb(GWEN_GUI *gwen_gui, guint32 flags,
const gchar *title,
125 const gchar *text, guint32 guiid);
126 static void GWENHYWFAR_CB hidebox_cb(GWEN_GUI *gwen_gui, guint32
id);
127 static guint32 GNC_GWENHYWFAR_CB progress_start_cb(GWEN_GUI *gwen_gui, uint32_t progressFlags,
128 const char *title,
const char *text,
129 uint64_t total, uint32_t guiid);
130 static gint GNC_GWENHYWFAR_CB progress_advance_cb(GWEN_GUI *gwen_gui, uint32_t
id,
131 uint64_t new_progress);
132 static gint GNC_GWENHYWFAR_CB progress_log_cb(GWEN_GUI *gwen_gui, guint32
id,
133 GWEN_LOGGER_LEVEL level,
const gchar *text);
134 static gint GNC_GWENHYWFAR_CB progress_end_cb(GWEN_GUI *gwen_gui, guint32
id);
135 static gint GNC_GWENHYWFAR_CB getpassword_cb(GWEN_GUI *gwen_gui, guint32 flags,
138 const gchar *text, gchar *buffer,
139 gint min_len, gint max_len,
140 GWEN_GUI_PASSWORD_METHOD methodId,
141 GWEN_DB_NODE *methodParams,
143 static gint GNC_GWENHYWFAR_CB setpasswordstatus_cb(GWEN_GUI *gwen_gui,
const gchar *token,
145 GWEN_GUI_PASSWORD_STATUS status, guint32 guiid);
146 static gint GNC_GWENHYWFAR_CB loghook_cb(GWEN_GUI *gwen_gui,
const gchar *log_domain,
147 GWEN_LOGGER_LEVEL priority,
const gchar *text);
148 typedef GWEN_SYNCIO GWEN_IO_LAYER;
149 static gint GNC_GWENHYWFAR_CB checkcert_cb(GWEN_GUI *gwen_gui,
const GWEN_SSLCERTDESCR *cert,
150 GWEN_IO_LAYER *io, guint32 guiid);
152 gboolean ggg_delete_event_cb(GtkWidget *widget, GdkEvent *event,
154 void ggg_abort_clicked_cb(GtkButton *button, gpointer user_data);
155 void ggg_close_clicked_cb(GtkButton *button, gpointer user_data);
156 void ggg_close_toggled_cb(GtkToggleButton *button, gpointer user_data);
174 GtkWidget *entries_grid;
175 GtkWidget *top_entry;
176 GtkWidget *top_progress;
177 GtkWidget *second_entry;
178 GtkWidget *other_entries_box;
185 guint64 current_action;
191 GtkWidget *abort_button;
192 GtkWidget *close_button;
193 GtkWidget *close_checkbutton;
200 gboolean cache_passwords;
201 GHashTable *passwords;
204 GHashTable *accepted_certs;
205 GWEN_DB_NODE *permanently_accepted_certs;
206 GWEN_GUI_CHECKCERT_FN builtin_checkcert;
210 GHashTable *showbox_hash;
211 GtkWidget *showbox_last;
214 GWEN_LOGGER_LEVEL min_loglevel;
233 log_gwen_gui = Gtk3_Gui_new();
236 GWEN_Gui_SetLogHookFn(log_gwen_gui, loghook_cb);
239 GWEN_Gui_Attach(log_gwen_gui);
241 GWEN_Gui_SetGui(log_gwen_gui);
249 ENTER(
"parent=%p", parent);
253 if (full_gui->state == INIT || full_gui->state == RUNNING)
255 LEAVE(
"full_gui in use, state=%d", full_gui->state);
260 gui->parent = parent;
262 register_callbacks(gui);
264 LEAVE(
"gui=%p", gui);
268 gui = g_new0(GncGWENGui, 1);
269 gui->parent = parent;
271 register_callbacks(gui);
275 LEAVE(
"new gui=%p", gui);
282 g_return_if_fail(gui && gui == full_gui);
285 ENTER(
"gui=%p", gui);
292 GncGWENGui *gui = full_gui;
298 GWEN_Gui_free(log_gwen_gui);
301 GWEN_Gui_SetGui(NULL);
309 g_hash_table_destroy(gui->passwords);
310 if (gui->showbox_hash)
311 g_hash_table_destroy(gui->showbox_hash);
312 if (gui->permanently_accepted_certs)
313 GWEN_DB_Group_free(gui->permanently_accepted_certs);
314 if (gui->accepted_certs)
315 g_hash_table_destroy(gui->accepted_certs);
316 gtk_widget_destroy(gui->dialog);
328 GNC_PREFS_GROUP_AQBANKING, GNC_PREF_CLOSE_ON_FINISH,
329 close_when_finished);
333 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(full_gui->close_checkbutton))
334 != close_when_finished)
336 gtk_toggle_button_set_active(
337 GTK_TOGGLE_BUTTON(full_gui->close_checkbutton),
338 close_when_finished);
352 GncGWENGui *gui = full_gui;
362 if (gui->state == HIDDEN)
364 gui->state = FINISHED;
366 gtk_toggle_button_set_active(
367 GTK_TOGGLE_BUTTON(gui->close_checkbutton),
370 gtk_widget_set_sensitive(gui->close_button, TRUE);
372 show_dialog(gui, FALSE);
383 GncGWENGui *gui = full_gui;
392 register_callbacks(GncGWENGui *gui)
396 g_return_if_fail(gui && !gui->gwen_gui);
398 ENTER(
"gui=%p", gui);
400 gwen_gui = Gtk3_Gui_new();
401 gui->gwen_gui = gwen_gui;
403 GWEN_Gui_SetMessageBoxFn(gwen_gui, messagebox_cb);
404 GWEN_Gui_SetInputBoxFn(gwen_gui, inputbox_cb);
405 GWEN_Gui_SetShowBoxFn(gwen_gui, showbox_cb);
406 GWEN_Gui_SetHideBoxFn(gwen_gui, hidebox_cb);
407 GWEN_Gui_SetProgressStartFn(gwen_gui, progress_start_cb);
408 GWEN_Gui_SetProgressAdvanceFn(gwen_gui, progress_advance_cb);
409 GWEN_Gui_SetProgressLogFn(gwen_gui, progress_log_cb);
410 GWEN_Gui_SetProgressEndFn(gwen_gui, progress_end_cb);
411 GWEN_Gui_SetGetPasswordFn(gwen_gui, getpassword_cb);
412 GWEN_Gui_SetSetPasswordStatusFn(gwen_gui, setpasswordstatus_cb);
413 GWEN_Gui_SetLogHookFn(gwen_gui, loghook_cb);
414 gui->builtin_checkcert = GWEN_Gui_SetCheckCertFn(gwen_gui, checkcert_cb);
416 GWEN_Gui_SetGui(gwen_gui);
417 SETDATA_GUI(gwen_gui, gui);
423 unregister_callbacks(GncGWENGui *gui)
425 g_return_if_fail(gui);
427 ENTER(
"gui=%p", gui);
431 LEAVE(
"already unregistered");
438 gui->gwen_gui = NULL;
444 setup_dialog(GncGWENGui *gui)
449 g_return_if_fail(gui);
451 ENTER(
"gui=%p", gui);
453 builder = gtk_builder_new();
454 gnc_builder_add_from_file (builder,
"dialog-ab.glade",
"aqbanking_connection_dialog");
456 gui->dialog = GTK_WIDGET(gtk_builder_get_object (builder,
"aqbanking_connection_dialog"));
458 gui->entries_grid = GTK_WIDGET(gtk_builder_get_object (builder,
"entries_grid"));
459 gui->top_entry = GTK_WIDGET(gtk_builder_get_object (builder,
"top_entry"));
460 gui->top_progress = GTK_WIDGET(gtk_builder_get_object (builder,
"top_progress"));
461 gui->second_entry = GTK_WIDGET(gtk_builder_get_object (builder,
"second_entry"));
462 gui->other_entries_box = NULL;
463 gui->progresses = NULL;
464 gui->log_text = GTK_WIDGET(gtk_builder_get_object (builder,
"log_text"));
465 gui->abort_button = GTK_WIDGET(gtk_builder_get_object (builder,
"abort_button"));
466 gui->close_button = GTK_WIDGET(gtk_builder_get_object (builder,
"close_button"));
467 gui->close_checkbutton = GTK_WIDGET(gtk_builder_get_object (builder,
"close_checkbutton"));
468 gui->accepted_certs = NULL;
469 gui->permanently_accepted_certs = NULL;
470 gui->showbox_hash = NULL;
474 gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, gui);
476 gtk_toggle_button_set_active(
477 GTK_TOGGLE_BUTTON(gui->close_checkbutton),
480 component_id = gnc_register_gui_component(GWEN_GUI_CM_CLASS, NULL,
481 cm_close_handler, gui);
482 gnc_gui_component_set_session(component_id, gnc_get_current_session());
486 g_object_unref(G_OBJECT(builder));
494 enable_password_cache(GncGWENGui *gui, gboolean enabled)
496 g_return_if_fail(gui);
498 if (enabled && !gui->passwords)
501 gui->passwords = g_hash_table_new_full(
502 g_str_hash, g_str_equal, (GDestroyNotify) g_free,
503 (GDestroyNotify) erase_password);
505 else if (!enabled && gui->passwords)
508 g_hash_table_destroy(gui->passwords);
509 gui->passwords = NULL;
511 gui->cache_passwords = enabled;
515 reset_dialog(GncGWENGui *gui)
517 gboolean cache_passwords;
519 g_return_if_fail(gui);
521 ENTER(
"gui=%p", gui);
523 gtk_entry_set_text(GTK_ENTRY(gui->top_entry),
"");
524 gtk_entry_set_text(GTK_ENTRY(gui->second_entry),
"");
525 g_list_foreach(gui->progresses, (GFunc) free_progress, NULL);
526 g_list_free(gui->progresses);
527 gui->progresses = NULL;
529 if (gui->other_entries_box)
531 gtk_grid_remove_row (GTK_GRID(gui->entries_grid),
532 OTHER_ENTRIES_ROW_OFFSET);
533 gtk_widget_destroy(gui->other_entries_box);
534 gui->other_entries_box = NULL;
536 if (gui->showbox_hash)
537 g_hash_table_destroy(gui->showbox_hash);
538 gui->showbox_last = NULL;
539 gui->showbox_hash = g_hash_table_new_full(
540 NULL, NULL, NULL, (GDestroyNotify) gtk_widget_destroy);
543 gtk_window_set_transient_for(GTK_WINDOW(gui->dialog),
544 GTK_WINDOW(gui->parent));
545 gnc_restore_window_size(GNC_PREFS_GROUP_CONNECTION,
546 GTK_WINDOW(gui->dialog), GTK_WINDOW(gui->parent));
548 gui->keep_alive = TRUE;
550 gui->min_loglevel = GWEN_LoggerLevel_Verbous;
553 GNC_PREF_REMEMBER_PIN);
554 enable_password_cache(gui, cache_passwords);
556 if (!gui->accepted_certs)
557 gui->accepted_certs = g_hash_table_new_full(
558 g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL);
559 if (!gui->permanently_accepted_certs)
566 set_running(GncGWENGui *gui)
568 g_return_if_fail(gui);
570 ENTER(
"gui=%p", gui);
572 gui->state = RUNNING;
573 gtk_widget_set_sensitive(gui->abort_button, TRUE);
574 gtk_widget_set_sensitive(gui->close_button, FALSE);
575 gui->keep_alive = TRUE;
581 set_finished(GncGWENGui *gui)
583 g_return_if_fail(gui);
585 ENTER(
"gui=%p", gui);
588 gui->state = FINISHED;
589 unregister_callbacks(gui);
591 gtk_widget_set_sensitive(gui->abort_button, FALSE);
592 gtk_widget_set_sensitive(gui->close_button, TRUE);
593 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gui->close_checkbutton)))
600 set_aborted(GncGWENGui *gui)
602 g_return_if_fail(gui);
604 ENTER(
"gui=%p", gui);
607 gui->state = ABORTED;
608 unregister_callbacks(gui);
610 gtk_widget_set_sensitive(gui->abort_button, FALSE);
611 gtk_widget_set_sensitive(gui->close_button, TRUE);
612 gui->keep_alive = FALSE;
618 show_dialog(GncGWENGui *gui, gboolean clear_log)
620 g_return_if_fail(gui);
622 ENTER(
"gui=%p, clear_log=%d", gui, clear_log);
624 gtk_widget_show(gui->dialog);
631 gtk_text_buffer_set_text(
632 gtk_text_view_get_buffer(GTK_TEXT_VIEW(gui->log_text)),
"", 0);
639 hide_dialog(GncGWENGui *gui)
641 g_return_if_fail(gui);
643 ENTER(
"gui=%p", gui);
646 gtk_widget_hide(gui->dialog);
652 GNC_PREFS_GROUP_AQBANKING, GNC_PREF_CLOSE_ON_FINISH,
653 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gui->close_checkbutton)));
656 gnc_save_window_size(GNC_PREFS_GROUP_CONNECTION, GTK_WINDOW(gui->dialog));
660 unregister_callbacks(gui);
666 show_progress_cb(gpointer user_data)
668 Progress *progress = user_data;
670 g_return_val_if_fail(progress, FALSE);
672 ENTER(
"progress=%p", progress);
674 show_progress(progress->gui, progress);
684 show_progress(GncGWENGui *gui, Progress *progress)
689 g_return_if_fail(gui);
691 ENTER(
"gui=%p, progress=%p", gui, progress);
693 for (item = g_list_last(gui->progresses); item; item = item->prev)
695 current = (Progress*) item->data;
698 && current != progress)
706 show_dialog(gui, TRUE);
707 gtk_entry_set_text(GTK_ENTRY(gui->top_entry), current->title);
709 else if (!item->next->next)
712 gtk_entry_set_text(GTK_ENTRY(gui->second_entry), current->title);
717 GtkWidget *entry = gtk_entry_new();
718 GtkWidget *box = gui->other_entries_box;
719 gboolean new_box = box == NULL;
721 gtk_entry_set_text(GTK_ENTRY(entry), current->title);
724 gui->other_entries_box = box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
725 gtk_box_set_homogeneous (GTK_BOX (gui->other_entries_box), TRUE);
726 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
729 gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0);
730 gtk_widget_show(entry);
733 gtk_grid_attach (GTK_GRID(gui->entries_grid), box,
734 1, OTHER_ENTRIES_ROW_OFFSET, 1, 1);
735 gtk_widget_show(box);
742 g_source_remove(current->source);
746 if (current == progress)
757 hide_progress(GncGWENGui *gui, Progress *progress)
762 g_return_if_fail(gui);
764 ENTER(
"gui=%p, progress=%p", gui, progress);
766 for (item = gui->progresses; item; item = item->next)
768 current = (Progress*) item->data;
773 g_source_remove(current->source);
775 if (current == progress)
785 gtk_entry_set_text(GTK_ENTRY(gui->second_entry),
"");
787 else if (!item->next->next)
790 gtk_entry_set_text(GTK_ENTRY(gui->second_entry),
"");
795 GtkWidget *box = gui->other_entries_box;
798 g_return_if_fail(box);
799 entries = gtk_container_get_children(GTK_CONTAINER(box));
800 g_return_if_fail(entries);
804 gtk_widget_destroy(GTK_WIDGET(g_list_last(entries)->data));
809 gtk_grid_remove_row (GTK_GRID(gui->entries_grid),
810 OTHER_ENTRIES_ROW_OFFSET);
812 gui->other_entries_box = NULL;
814 g_list_free(entries);
817 if (current == progress)
825 free_progress(Progress *progress, gpointer unused)
827 if (progress->source)
828 g_source_remove(progress->source);
829 g_free(progress->title);
834 keep_alive(GncGWENGui *gui)
836 g_return_val_if_fail(gui, FALSE);
838 ENTER(
"gui=%p", gui);
841 while (g_main_context_iteration(NULL, FALSE));
843 LEAVE(
"alive=%d", gui->keep_alive);
844 return gui->keep_alive;
848 cm_close_handler(gpointer user_data)
850 GncGWENGui *gui = user_data;
852 g_return_if_fail(gui);
854 ENTER(
"gui=%p", gui);
863 erase_password(gchar *password)
865 g_return_if_fail(password);
869 memset(password, 0, strlen(password));
879 strip_html(gchar *text)
887 while (strchr(p,
'<'))
890 if (*q && toupper(*q++) ==
'H' 891 && *q && toupper(*q++) ==
'T' 892 && *q && toupper(*q++) ==
'M' 893 && *q && toupper(*q) ==
'L')
904 get_input(GncGWENGui *gui, guint32 flags,
const gchar *title,
905 const gchar *text,
const char *mimeType,
906 const char *pChallenge, uint32_t lChallenge,
907 gchar **input, gint min_len, gint max_len)
911 GtkWidget *heading_label;
912 GtkWidget *input_entry;
913 GtkWidget *confirm_entry;
914 GtkWidget *confirm_label;
915 GtkWidget *remember_pin_checkbutton;
916 GtkImage *optical_challenge;
920 const gchar *internal_input, *internal_confirmed;
921 gboolean confirm = (flags & GWEN_GUI_INPUT_FLAGS_CONFIRM) != 0;
922 gboolean is_tan = (flags & GWEN_GUI_INPUT_FLAGS_TAN) != 0;
924 g_return_if_fail(input);
925 g_return_if_fail(max_len >= min_len && max_len > 0);
930 builder = gtk_builder_new();
931 gnc_builder_add_from_file (builder,
"dialog-ab.glade",
"aqbanking_password_dialog");
932 dialog = GTK_WIDGET(gtk_builder_get_object (builder,
"aqbanking_password_dialog"));
934 heading_label = GTK_WIDGET(gtk_builder_get_object (builder,
"heading_pw_label"));
935 input_entry = GTK_WIDGET(gtk_builder_get_object (builder,
"input_entry"));
936 confirm_entry = GTK_WIDGET(gtk_builder_get_object (builder,
"confirm_entry"));
937 confirm_label = GTK_WIDGET(gtk_builder_get_object (builder,
"confirm_label"));
938 remember_pin_checkbutton = GTK_WIDGET(gtk_builder_get_object (builder,
"remember_pin"));
939 optical_challenge = GTK_IMAGE(gtk_builder_get_object (builder,
"optical_challenge"));
940 gtk_widget_set_visible(GTK_WIDGET(optical_challenge), FALSE);
943 flickergui->flicker_challenge = GTK_WIDGET(gtk_builder_get_object(builder,
"flicker_challenge"));
944 flickergui->flicker_marker = GTK_WIDGET(gtk_builder_get_object(builder,
"flicker_marker"));
945 flickergui->flicker_hbox = GTK_WIDGET(gtk_builder_get_object(builder,
"flicker_hbox"));
946 flickergui->spin_barwidth = GTK_SPIN_BUTTON(gtk_builder_get_object(builder,
"spin_barwidth"));
947 flickergui->spin_delay = GTK_SPIN_BUTTON(gtk_builder_get_object(builder,
"spin_delay"));
949 gtk_widget_set_visible(GTK_WIDGET(flickergui->flicker_challenge), FALSE);
950 gtk_widget_set_visible(GTK_WIDGET(flickergui->flicker_marker), FALSE);
951 gtk_widget_set_visible(GTK_WIDGET(flickergui->flicker_hbox), FALSE);
952 gtk_widget_set_visible(GTK_WIDGET(flickergui->spin_barwidth), FALSE);
953 gtk_widget_set_visible(GTK_WIDGET(flickergui->spin_delay), FALSE);
955 if (g_strcmp0(mimeType,
"text/x-flickercode") == 0 && pChallenge != NULL)
958 gtk_widget_set_visible(GTK_WIDGET(flickergui->flicker_challenge), TRUE);
959 gtk_widget_set_visible(GTK_WIDGET(flickergui->flicker_marker), TRUE);
960 gtk_widget_set_visible(GTK_WIDGET(flickergui->flicker_hbox), TRUE);
961 gtk_widget_set_visible(GTK_WIDGET(flickergui->spin_barwidth), TRUE);
962 gtk_widget_set_visible(GTK_WIDGET(flickergui->spin_delay), TRUE);
964 else if(mimeType != NULL && pChallenge != NULL && lChallenge > 0)
967 gtk_widget_set_visible(GTK_WIDGET(optical_challenge), TRUE);
971 gtk_widget_hide(remember_pin_checkbutton);
975 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(remember_pin_checkbutton),
976 gui->cache_passwords);
980 if ((flags & (GWEN_GUI_INPUT_FLAGS_TAN | GWEN_GUI_INPUT_FLAGS_SHOW)) != 0)
982 gtk_widget_set_visible(input_entry, TRUE);
983 gtk_entry_set_visibility(GTK_ENTRY(input_entry), TRUE);
988 gtk_window_set_transient_for(GTK_WINDOW(dialog),
989 GTK_WINDOW(gui->dialog));
994 gtk_window_set_transient_for(GTK_WINDOW(dialog),
995 GTK_WINDOW(gui->parent));
998 gtk_window_set_title(GTK_WINDOW(dialog), title);
1002 gchar *raw_text = strip_html(g_strdup(text));
1003 gtk_label_set_text(GTK_LABEL(heading_label), raw_text);
1009 if (g_strcmp0(mimeType,
"text/x-flickercode") == 0 && pChallenge != NULL)
1012 flickergui->dialog = dialog;
1013 flickergui->input_entry = input_entry;
1020 else if(mimeType != NULL && pChallenge != NULL && lChallenge > 0)
1025 guchar *gudata = (guchar*)pChallenge;
1027 GError *error = NULL;
1028 GdkPixbufLoader *loader = gdk_pixbuf_loader_new_with_mime_type(mimeType, &error);
1033 PERR(
"Pixbuf loader not loaded: %s, perhaps MIME type %s isn't supported.", error->message, mimeType);
1036 gdk_pixbuf_loader_write(loader, gudata, lChallenge, NULL);
1037 gdk_pixbuf_loader_close(loader, NULL);
1039 pixbuf = gdk_pixbuf_loader_get_pixbuf(loader);
1041 g_object_ref(pixbuf);
1042 g_object_unref(loader);
1044 gtk_image_set_from_pixbuf(optical_challenge, pixbuf);
1049 gtk_entry_set_text(GTK_ENTRY(input_entry), *input);
1050 erase_password(*input);
1056 gtk_entry_set_activates_default(GTK_ENTRY(input_entry), FALSE);
1057 gtk_entry_set_activates_default(GTK_ENTRY(confirm_entry), TRUE);
1058 gtk_entry_set_max_length(GTK_ENTRY(input_entry), max_len);
1059 gtk_entry_set_max_length(GTK_ENTRY(confirm_entry), max_len);
1063 gtk_entry_set_activates_default(GTK_ENTRY(input_entry), TRUE);
1064 gtk_entry_set_max_length(GTK_ENTRY(input_entry), max_len);
1065 gtk_widget_hide(confirm_entry);
1066 gtk_widget_hide(confirm_label);
1068 gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
1073 gboolean remember_pin;
1075 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK)
1081 remember_pin = gtk_toggle_button_get_active(
1082 GTK_TOGGLE_BUTTON(remember_pin_checkbutton));
1083 enable_password_cache(gui, remember_pin);
1088 internal_input = gtk_entry_get_text(GTK_ENTRY(input_entry));
1089 if (strlen(internal_input) < min_len)
1092 gchar *msg = g_strdup_printf(
1093 _(
"The PIN needs to be at least %d characters\n" 1094 "long. Do you want to try again?"), min_len);
1095 retval = gnc_verify_dialog (GTK_WINDOW (gui->parent), TRUE,
"%s", msg);
1104 *input = g_strdup(internal_input);
1108 internal_confirmed = gtk_entry_get_text(GTK_ENTRY(confirm_entry));
1109 if (strcmp(internal_input, internal_confirmed) == 0)
1111 *input = g_strdup(internal_input);
1116 g_object_unref(G_OBJECT(builder));
1119 gtk_widget_destroy(dialog);
1121 LEAVE(
"input %s", *input ?
"non-NULL" :
"NULL");
1124 static gint GNC_GWENHYWFAR_CB
1125 messagebox_cb(GWEN_GUI *gwen_gui, guint32 flags,
const gchar *title,
1126 const gchar *text,
const gchar *b1,
const gchar *b2,
1127 const gchar *b3, guint32 guiid)
1129 GncGWENGui *gui = GETDATA_GUI(gwen_gui);
1136 ENTER(
"gui=%p, flags=%d, title=%s, b1=%s, b2=%s, b3=%s", gui, flags,
1137 title ? title :
"(null)", b1 ? b1 :
"(null)", b2 ? b2 :
"(null)",
1138 b3 ? b3 :
"(null)");
1140 dialog = gtk_dialog_new_with_buttons(
1141 title, gui->parent ? GTK_WINDOW(gui->parent) : NULL,
1142 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
1143 b1, 1, b2, 2, b3, 3, (gchar*) NULL);
1145 raw_text = strip_html(g_strdup(text));
1146 label = gtk_label_new(raw_text);
1148 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
1149 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
1150 gtk_box_set_homogeneous (GTK_BOX (vbox), TRUE);
1151 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1152 gtk_container_add(GTK_CONTAINER(vbox), label);
1153 gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
1154 gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area (GTK_DIALOG(dialog))), vbox);
1155 gtk_widget_show_all(dialog);
1157 result = gtk_dialog_run(GTK_DIALOG(dialog));
1158 gtk_widget_destroy(dialog);
1160 if (result < 1 || result > 3)
1162 g_warning(
"messagebox_cb: Bad result %d", result);
1166 LEAVE(
"result=%d", result);
1170 static gint GNC_GWENHYWFAR_CB
1171 inputbox_cb(GWEN_GUI *gwen_gui, guint32 flags,
const gchar *title,
1172 const gchar *text, gchar *buffer, gint min_len, gint max_len,
1175 GncGWENGui *gui = GETDATA_GUI(gwen_gui);
1176 gchar *input = NULL;
1178 g_return_val_if_fail(gui, -1);
1180 ENTER(
"gui=%p, flags=%d", gui, flags);
1182 get_input(gui, flags, title, text, NULL, NULL, 0, &input, min_len, max_len);
1187 strncpy(buffer, input, max_len);
1188 buffer[max_len-1] =
'\0';
1192 return input ? 0 : -1;
1195 static guint32 GNC_GWENHYWFAR_CB
1196 showbox_cb(GWEN_GUI *gwen_gui, guint32 flags,
const gchar *title,
1197 const gchar *text, guint32 guiid)
1199 GncGWENGui *gui = GETDATA_GUI(gwen_gui);
1203 g_return_val_if_fail(gui, -1);
1205 ENTER(
"gui=%p, flags=%d, title=%s", gui, flags, title ? title :
"(null)");
1207 dialog = gtk_message_dialog_new(
1208 gui->parent ? GTK_WINDOW(gui->parent) : NULL, 0, GTK_MESSAGE_INFO,
1209 GTK_BUTTONS_OK,
"%s", text);
1212 gtk_window_set_title(GTK_WINDOW(dialog), title);
1214 g_signal_connect(dialog,
"response", G_CALLBACK(gtk_widget_hide), NULL);
1215 gtk_widget_show_all(dialog);
1217 showbox_id = gui->showbox_id++;
1218 g_hash_table_insert(gui->showbox_hash, GUINT_TO_POINTER(showbox_id),
1220 gui->showbox_last = dialog;
1223 if (!keep_alive(gui))
1226 LEAVE(
"id=%" G_GUINT32_FORMAT, showbox_id);
1230 static void GNC_GWENHYWFAR_CB
1231 hidebox_cb(GWEN_GUI *gwen_gui, guint32
id)
1233 GncGWENGui *gui = GETDATA_GUI(gwen_gui);
1235 g_return_if_fail(gui && gui->showbox_hash);
1237 ENTER(
"gui=%p, id=%d", gui,
id);
1241 if (gui->showbox_last)
1243 g_hash_table_remove(gui->showbox_hash,
1244 GUINT_TO_POINTER(gui->showbox_id));
1245 gui->showbox_last = NULL;
1249 g_warning(
"hidebox_cb: Last showed message box already destroyed");
1255 p_var = g_hash_table_lookup(gui->showbox_hash, GUINT_TO_POINTER(
id));
1258 g_hash_table_remove(gui->showbox_hash, GUINT_TO_POINTER(
id));
1259 if (p_var == gui->showbox_last)
1260 gui->showbox_last = NULL;
1264 g_warning(
"hidebox_cb: Message box %d could not been found",
id);
1271 static guint32 GNC_GWENHYWFAR_CB
1272 progress_start_cb(GWEN_GUI *gwen_gui, uint32_t progressFlags,
const char *title,
1273 const char *text, uint64_t total, uint32_t guiid)
1275 GncGWENGui *gui = GETDATA_GUI(gwen_gui);
1278 g_return_val_if_fail(gui, -1);
1280 ENTER(
"gui=%p, flags=%d, title=%s, total=%" G_GUINT64_FORMAT, gui,
1281 progressFlags, title ? title :
"(null)", (guint64)total);
1283 if (!gui->progresses)
1286 if (progressFlags & GWEN_GUI_PROGRESS_SHOW_PROGRESS)
1288 gtk_widget_set_sensitive(gui->top_progress, TRUE);
1289 gtk_progress_bar_set_fraction(
1290 GTK_PROGRESS_BAR(gui->top_progress), 0.0);
1291 gui->max_actions = total;
1295 gtk_widget_set_sensitive(gui->top_progress, FALSE);
1296 gui->max_actions = -1;
1302 progress = g_new0(Progress, 1);
1303 progress->gui = gui;
1304 progress->title = title ? g_strdup(title) :
"";
1305 gui->progresses = g_list_prepend(gui->progresses, progress);
1307 if (progressFlags & GWEN_GUI_PROGRESS_DELAY)
1310 progress->source = g_timeout_add(GWEN_GUI_DELAY_SECS * 1000,
1311 (GSourceFunc) show_progress_cb,
1317 progress->source = 0;
1318 show_progress(gui, progress);
1322 return g_list_length(gui->progresses);
1325 static gint GNC_GWENHYWFAR_CB
1326 progress_advance_cb(GWEN_GUI *gwen_gui, uint32_t
id, uint64_t progress)
1328 GncGWENGui *gui = GETDATA_GUI(gwen_gui);
1330 g_return_val_if_fail(gui, -1);
1332 ENTER(
"gui=%p, progress=%" G_GUINT64_FORMAT, gui, (guint64)progress);
1335 && gui->max_actions > 0
1336 && progress != GWEN_GUI_PROGRESS_NONE)
1338 if (progress == GWEN_GUI_PROGRESS_ONE)
1339 gui->current_action++;
1341 gui->current_action = progress;
1343 gtk_progress_bar_set_fraction(
1344 GTK_PROGRESS_BAR(gui->top_progress),
1345 ((gdouble) gui->current_action) / ((gdouble) gui->max_actions));
1349 return !keep_alive(gui);
1352 static gint GNC_GWENHYWFAR_CB
1353 progress_log_cb(GWEN_GUI *gwen_gui, guint32
id, GWEN_LOGGER_LEVEL level,
1356 GncGWENGui *gui = GETDATA_GUI(gwen_gui);
1360 g_return_val_if_fail(gui, -1);
1362 ENTER(
"gui=%p, text=%s", gui, text ? text :
"(null)");
1364 tv = GTK_TEXT_VIEW(gui->log_text);
1365 tb = gtk_text_view_get_buffer(tv);
1366 gtk_text_buffer_insert_at_cursor(tb, text, -1);
1367 gtk_text_buffer_insert_at_cursor(tb,
"\n", -1);
1370 gtk_text_view_scroll_to_mark(tv, gtk_text_buffer_get_insert(tb),
1371 0.0, FALSE, 0.0, 0.0);
1374 if (level < gui->min_loglevel)
1375 gui->min_loglevel = level;
1378 return !keep_alive(gui);
1381 static gint GNC_GWENHYWFAR_CB
1382 progress_end_cb(GWEN_GUI *gwen_gui, guint32
id)
1384 GncGWENGui *gui = GETDATA_GUI(gwen_gui);
1387 g_return_val_if_fail(gui, -1);
1388 g_return_val_if_fail(
id == g_list_length(gui->progresses), -1);
1390 ENTER(
"gui=%p, id=%d", gui,
id);
1392 if (gui->state != RUNNING)
1395 LEAVE(
"not running anymore");
1400 progress = (Progress*) gui->progresses->data;
1401 hide_progress(gui, progress);
1404 gui->progresses = g_list_delete_link(gui->progresses, gui->progresses);
1405 free_progress(progress, NULL);
1407 if (!gui->progresses)
1417 static gint GNC_GWENHYWFAR_CB
1418 getpassword_cb(GWEN_GUI *gwen_gui, guint32 flags,
const gchar *token,
1419 const gchar *title,
const gchar *text, gchar *buffer,
1420 gint min_len, gint max_len, GWEN_GUI_PASSWORD_METHOD methodId,
1421 GWEN_DB_NODE *methodParams, guint32 guiid)
1423 GncGWENGui *gui = GETDATA_GUI(gwen_gui);
1424 gchar *password = NULL;
1425 gboolean is_tan = (flags & GWEN_GUI_INPUT_FLAGS_TAN) != 0;
1427 int opticalMethodId;
1428 const char *mimeType = NULL;
1429 const char *pChallenge = NULL;
1430 uint32_t lChallenge = 0;
1432 g_return_val_if_fail(gui, -1);
1435 if(is_tan && methodId == GWEN_Gui_PasswordMethod_OpticalHHD)
1441 opticalMethodId=GWEN_DB_GetIntValue(methodParams,
"tanMethodId", 0, AB_BANKING_TANMETHOD_TEXT);
1442 switch(opticalMethodId)
1444 case AB_BANKING_TANMETHOD_CHIPTAN:
1446 case AB_BANKING_TANMETHOD_CHIPTAN_OPTIC:
1447 mimeType =
"text/x-flickercode";
1448 pChallenge = GWEN_DB_GetCharValue(methodParams,
"challenge", 0, NULL);
1449 if ((pChallenge == NULL) || (pChallenge[0] ==
'\0'))
1452 return GWEN_ERROR_NO_DATA;
1455 case AB_BANKING_TANMETHOD_CHIPTAN_USB:
1460 case AB_BANKING_TANMETHOD_PHOTOTAN:
1461 case AB_BANKING_TANMETHOD_CHIPTAN_QR:
1465 mimeType=GWEN_DB_GetCharValue(methodParams,
"mimeType", 0, NULL);
1466 pChallenge=(
const char*) GWEN_DB_GetBinValue(methodParams,
"imageData", 0, NULL, 0, &lChallenge);
1467 if (!(pChallenge && lChallenge))
1470 return GWEN_ERROR_NO_DATA;
1478 ENTER(
"gui=%p, flags=%d, token=%s", gui, flags, token ? token :
"(null");
1481 if (!is_tan && gui->cache_passwords && gui->passwords && token)
1483 if (flags & GWEN_GUI_INPUT_FLAGS_RETRY)
1486 g_hash_table_remove(gui->passwords, token);
1491 if (g_hash_table_lookup_extended(gui->passwords, token, NULL,
1496 strncpy(buffer, password, max_len);
1497 buffer[max_len-1] =
'\0';
1499 LEAVE(
"chose remembered password");
1505 get_input(gui, flags, title, text, mimeType, pChallenge, lChallenge, &password, min_len, max_len);
1510 strncpy(buffer, password, max_len);
1511 buffer[max_len-1] =
'\0';
1513 if (!is_tan && token)
1515 if (gui->cache_passwords && gui->passwords)
1518 DEBUG(
"Remember password, token=%s", token);
1519 g_hash_table_insert(gui->passwords, g_strdup(token), password);
1524 DEBUG(
"Forget password, token=%s", token);
1525 erase_password(password);
1531 return password ? 0 : -1;
1534 static gint GNC_GWENHYWFAR_CB
1535 setpasswordstatus_cb(GWEN_GUI *gwen_gui,
const gchar *token,
const gchar *pin,
1536 GWEN_GUI_PASSWORD_STATUS status, guint32 guiid)
1538 GncGWENGui *gui = GETDATA_GUI(gwen_gui);
1540 g_return_val_if_fail(gui, -1);
1542 ENTER(
"gui=%p, token=%s, status=%d", gui, token ? token :
"(null)", status);
1544 if (gui->passwords && status != GWEN_Gui_PasswordStatus_Ok)
1547 g_hash_table_remove(gui->passwords, token);
1554 static gint GNC_GWENHYWFAR_CB
1555 loghook_cb(GWEN_GUI *gwen_gui,
const gchar *log_domain,
1556 GWEN_LOGGER_LEVEL priority,
const gchar *text)
1558 if (G_LIKELY(priority < n_log_levels))
1559 g_log(log_domain, log_levels[priority],
"%s", text);
1564 static gint GNC_GWENHYWFAR_CB
1565 checkcert_cb(GWEN_GUI *gwen_gui,
const GWEN_SSLCERTDESCR *cert,
1566 GWEN_IO_LAYER *io, guint32 guiid)
1568 GncGWENGui *gui = GETDATA_GUI(gwen_gui);
1569 const gchar *hash, *status;
1570 GChecksum *gcheck = g_checksum_new (G_CHECKSUM_MD5);
1571 gchar cert_hash[16];
1575 g_return_val_if_fail(gui && gui->accepted_certs, -1);
1577 ENTER(
"gui=%p, cert=%p", gui, cert);
1579 hash = GWEN_SslCertDescr_GetFingerPrint(cert);
1580 status = GWEN_SslCertDescr_GetStatusText(cert);
1582 g_checksum_update (gcheck, (
const guchar *)hash, strlen (hash));
1583 g_checksum_update (gcheck, (
const guchar *)status, strlen (status));
1586 if (gui->permanently_accepted_certs)
1589 retval = GWEN_DB_GetIntValue(gui->permanently_accepted_certs,
1590 g_checksum_get_string (gcheck), 0, -1);
1594 g_checksum_free (gcheck);
1595 LEAVE(
"Certificate accepted by AqBanking's permanent cert store");
1601 g_warning(
"Can't check permanently accepted certs from invalid AqBanking cert store.");
1604 g_checksum_get_digest (gcheck, (guint8 *)cert_hash, &hashlen);
1605 g_checksum_free (gcheck);
1606 g_assert (hashlen <=
sizeof (cert_hash));
1608 if (g_hash_table_lookup(gui->accepted_certs, cert_hash))
1611 LEAVE(
"Automatically accepting certificate");
1615 retval = gui->builtin_checkcert(gwen_gui, cert, io, guiid);
1619 g_hash_table_insert(gui->accepted_certs, g_strdup(cert_hash), cert_hash);
1622 LEAVE(
"retval=%d", retval);
1627 ggg_delete_event_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data)
1629 GncGWENGui *gui = user_data;
1631 g_return_val_if_fail(gui, FALSE);
1633 ENTER(
"gui=%p, state=%d", gui, gui->state);
1635 if (gui->state == RUNNING)
1637 const char *still_running_msg =
1638 _(
"The Online Banking job is still running; are you " 1639 "sure you want to cancel?");
1640 if (!gnc_verify_dialog (GTK_WINDOW (gui->dialog), FALSE,
"%s", still_running_msg))
1653 ggg_abort_clicked_cb(GtkButton *button, gpointer user_data)
1655 GncGWENGui *gui = user_data;
1657 g_return_if_fail(gui && gui->state == RUNNING);
1659 ENTER(
"gui=%p", gui);
1667 ggg_close_clicked_cb(GtkButton *button, gpointer user_data)
1669 GncGWENGui *gui = user_data;
1671 g_return_if_fail(gui);
1672 g_return_if_fail(gui->state == INIT || gui->state == FINISHED || gui->state == ABORTED);
1674 ENTER(
"gui=%p", gui);
1682 ggg_close_toggled_cb(GtkToggleButton *button, gpointer user_data)
1684 GncGWENGui *gui = user_data;
1686 g_return_if_fail(gui);
1687 g_return_if_fail(gui->parent);
1689 ENTER(
"gui=%p", gui);
1692 GNC_PREFS_GROUP_AQBANKING, GNC_PREF_CLOSE_ON_FINISH,
1693 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)));
gboolean gnc_GWEN_Gui_show_dialog()
Unhides Online Banking Connection Window (Make log visible)
void gnc_GWEN_Gui_shutdown(void)
Free all memory related to both the full-blown and minimalistic GUI objects.
#define G_LOG_DOMAIN
Functions providing the SX List as a plugin page.
gboolean gnc_GWEN_Gui_get_close_flag()
Get "Close when finished" flag.
#define DEBUG(format, args...)
Print a debugging message.
#define PERR(format, args...)
Log a serious error.
#define ENTER(format, args...)
Print a function entry debugging message.
GncGWENGui * gnc_GWEN_Gui_get(GtkWidget *parent)
When called for the first time, create a unique GncGWENGui object featuring a GWEN_GUI with all neces...
GWEN_DB_NODE * gnc_ab_get_permanent_certs(void)
get the GWEN_DB_NODE from AqBanking configuration files
void gnc_GWEN_Gui_release(GncGWENGui *gui)
Currently a no-op.
GUI callbacks for Flicker and ChipTAN(optisch)
void gnc_plugin_aqbanking_set_logwindow_visible(gboolean logwindow_visible)
Set MENU_TOGGLE_ACTION_AB_VIEW_LOGWINDOW.
gboolean gnc_prefs_set_bool(const gchar *group, const gchar *pref_name, gboolean value)
Store a boolean value into the preferences backend.
Generic api to store and retrieve preferences.
Plugin registration of the AqBanking module.
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
#define LEAVE(format, args...)
Print a function exit debugging message.
void ini_flicker_gui(const char *pChallenge, GncFlickerGui *gui)
Initialize the dialog and drawing area.
GUI callbacks for AqBanking.
void gnc_GWEN_Gui_log_init(void)
Hook our logging into the gwenhywfar logging framework by creating a minimalistic GWEN_GUI with only ...
AqBanking utility functions.
void gnc_GWEN_Gui_set_close_flag(gboolean close_when_finished)
Set "Close when finished" flag.
void gnc_GWEN_Gui_hide_dialog()
Hides Online Banking Connection Window (Close log window)