Blob Blame History Raw
From fc7246eb0957d301fc413947bcc961b9ad120f31 Mon Sep 17 00:00:00 2001
From: Matej Habrnal <mhabrnal@redhat.com>
Date: Mon, 8 Jun 2015 09:32:45 +0200
Subject: [PATCH] lib: add support for ask_yes_no_save_result

Related to rhbz#986876

Signed-off-by: Matej Habrnal <mhabrnal@redhat.com>
---
 src/gui-wizard-gtk/wizard.c |  8 ++++++++
 src/include/run_event.h     | 30 ++++++++++++++++++++++++++++++
 src/lib/run_event.c         | 38 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 76 insertions(+)

diff --git a/src/gui-wizard-gtk/wizard.c b/src/gui-wizard-gtk/wizard.c
index 513f0a3..a06e155 100644
--- a/src/gui-wizard-gtk/wizard.c
+++ b/src/gui-wizard-gtk/wizard.c
@@ -1730,6 +1730,13 @@ static int run_event_gtk_ask_yes_no_yesforever(const char *key, const char *msg,
     return ret;
 }
 
+static int run_event_gtk_ask_yes_no_save_result(const char *key, const char *msg, void *args)
+{
+    const int ret = run_ask_yes_no_save_result_dialog(key, msg, GTK_WINDOW(g_wnd_assistant));
+    log_request_response_communication(msg, ret ? "YES" : "NO", (struct analyze_event_data *)args);
+    return ret;
+}
+
 static char *run_event_gtk_ask_password(const char *msg, void *args)
 {
     return ask_helper(msg, args, true);
@@ -2066,6 +2073,7 @@ static void start_event_run(const char *event_name)
     state->ask_callback = run_event_gtk_ask;
     state->ask_yes_no_callback = run_event_gtk_ask_yes_no;
     state->ask_yes_no_yesforever_callback = run_event_gtk_ask_yes_no_yesforever;
+    state->ask_yes_no_save_result_callback = run_event_gtk_ask_yes_no_save_result;
     state->ask_password_callback = run_event_gtk_ask_password;
 
     if (prepare_commands(state, g_dump_dir_name, event_name) == 0)
diff --git a/src/include/run_event.h b/src/include/run_event.h
index 7579e8f..fdd9ec3 100644
--- a/src/include/run_event.h
+++ b/src/include/run_event.h
@@ -109,6 +109,22 @@ struct run_event_state {
     int (*ask_yes_no_yesforever_callback)(const char *key, const char *msg, void *interaction_param);
 
     /*
+     * Called when child command wants to know 'yes/no/forever/never' decision.
+     * The forever means that in next call the yes answer is returned
+     * immediately without asking. The never means that in next call the
+     * no answer is returned immediately without asking. The answer is stored
+     * in configuration under a passed key.
+     *
+     * The default value is run_event_stdio_ask_yes_no_save_result()
+     *
+     * @param key An option name used as a key in configuration
+     * @param msg An ask message produced by child command
+     * @param args An implementor args
+     * @return Return 0 if an answer is NO, otherwise return nonzero value.
+     */
+    int (*ask_yes_no_save_result_callback)(const char *key, const char *msg, void *interaction_param);
+
+    /*
      * Called when child wants to know a password.
      *
      * The default value is run_event_stdio_ask_password()
@@ -238,6 +254,20 @@ int run_event_stdio_ask_yes_no(const char *msg, void *param);
 int run_event_stdio_ask_yes_no_yesforever(const char *msg, const char *key, void *param);
 
 /*
+ * Prints the msg param on stdout and reads a response from stdin. To store the
+ * forever or never answer uses libreport's user settings API.
+ * Therefore if you want to get the forever or never stuff working you
+ * have to call load_user_setting() function before this function call and call
+ * save_user_settings() function after this function call.
+ *
+ * @param msg a printed message
+ * @param key a key under which the forever (yes) or never (no) answer is stored
+ * @param param ONLY NULL IS ALLOWED; other values are intended for internal use only
+ * @return 0 if user's answer is 'no', otherwise non 0 value
+ */
+int run_event_stdio_ask_yes_no_save_result(const char *msg, const char *key, void *param);
+
+/*
  * Prints the msg param on stdout and reads a response from stdin
  *
  * @param msg a printed message
diff --git a/src/lib/run_event.c b/src/lib/run_event.c
index a56cf88..d8b00fe 100644
--- a/src/lib/run_event.c
+++ b/src/lib/run_event.c
@@ -35,6 +35,7 @@ struct run_event_state *new_run_event_state()
     state->ask_callback = run_event_stdio_ask;
     state->ask_yes_no_callback = run_event_stdio_ask_yes_no;
     state->ask_yes_no_yesforever_callback= run_event_stdio_ask_yes_no_yesforever;
+    state->ask_yes_no_save_result_callback= run_event_stdio_ask_yes_no_save_result;
     state->ask_password_callback = run_event_stdio_ask_password;
 
     state->command_output = strbuf_new();
@@ -59,6 +60,7 @@ void make_run_event_state_forwarding(struct run_event_state *state)
     state->ask_callback = run_event_stdio_ask;
     state->ask_yes_no_callback = run_event_stdio_ask_yes_no;
     state->ask_yes_no_yesforever_callback= run_event_stdio_ask_yes_no_yesforever;
+    state->ask_yes_no_save_result_callback= run_event_stdio_ask_yes_no_save_result;
     state->ask_password_callback = run_event_stdio_ask_password;
 
     /*
@@ -532,6 +534,37 @@ int consume_event_command_output(struct run_event_state *state, const char *dump
 
                 response = xstrdup(ans ? "y" : "N");
             }
+            /* wait for y/N/f/e response on the same line */
+            else if (prefixcmp(msg, REPORT_PREFIX_ASK_YES_NO_SAVE_RESULT) == 0)
+            {
+                /* example:
+                 *   ASK_YES_NO_SAVE_RESULT ask_before_delete Do you want to delete selected files?
+                 */
+                char *key = msg + sizeof(REPORT_PREFIX_ASK_YES_NO_SAVE_RESULT) - 1;
+                char *key_end = strchr(key, ' ');
+
+                bool ans = false;
+
+                if (!key_end)
+                {   /* example:
+                     *  ASK_YES_NO_YESFOREVER Continue?
+                     *
+                     * Print a wraning only and do not scary users with error messages.
+                     */
+                    log_warning("invalid input format (missing option name), using simple ask yes/no");
+
+                    /* can't simply use 'goto ask_yes_no' because of different lenght of prefixes */
+                    ans = state->ask_yes_no_callback(key, state->interaction_param);
+                }
+                else
+                {
+                    key_end[0] = '\0'; /* split 'key msg' to 'key' and 'msg' */
+                    ans = state->ask_yes_no_save_result_callback(key, key + strlen(key) + 1, state->interaction_param);
+                    key_end[0] = ' '; /* restore original message, not sure if it is necessary */
+                }
+
+                response = xstrdup(ans ? "y" : "N");
+            }
             /* wait for y/N response on the same line */
             else if (prefixcmp(msg, REPORT_PREFIX_ASK_YES_NO) == 0)
             {
@@ -738,6 +771,11 @@ int run_event_stdio_ask_yes_no_yesforever(const char *key, const char *msg, void
     return ask_yes_no_yesforever(key, msg);
 }
 
+int run_event_stdio_ask_yes_no_save_result(const char *key, const char *msg, void *param)
+{
+    return ask_yes_no_save_result(key, msg);
+}
+
 char *run_event_stdio_ask_password(const char *msg, void *param)
 {
     return ask_password(msg);
-- 
2.1.0