ui/ncurses: Add nc-auth and authenticate when required.
[petitboot] / ui / ncurses / nc-add-url.c
index b1a31dd391cff155ee13707027187662543d774b..33f502da349c584f367a00442adc94db147a334f 100644 (file)
@@ -28,6 +28,7 @@
 #include <i18n/i18n.h>
 #include <log/log.h>
 
+#include "ui/common/discover-client.h"
 #include "nc-cui.h"
 #include "nc-add-url.h"
 #include "nc-widgets.h"
@@ -40,11 +41,15 @@ struct add_url_screen {
        struct nc_scr           scr;
        struct cui              *cui;
        struct nc_widgetset     *widgetset;
+       WINDOW                  *pad;
 
        bool                    exit;
        bool                    show_help;
+       bool                    need_redraw;
        void                    (*on_exit)(struct cui *);
 
+       int                     scroll_y;
+
        int                     label_x;
        int                     field_x;
 
@@ -69,6 +74,16 @@ static struct add_url_screen *add_url_screen_from_scr(struct nc_scr *scr)
        return add_url_screen;
 }
 
+static void pad_refresh(struct add_url_screen *screen)
+{
+       int y, x, rows, cols;
+
+       getmaxyx(screen->scr.sub_ncw, rows, cols);
+       getbegyx(screen->scr.sub_ncw, y, x);
+
+       prefresh(screen->pad, screen->scroll_y, 0, y, x, rows, cols);
+}
+
 static void add_url_screen_process_key(struct nc_scr *scr, int key)
 {
        struct add_url_screen *screen = add_url_screen_from_scr(scr);
@@ -93,21 +108,49 @@ static void add_url_screen_process_key(struct nc_scr *scr, int key)
 
        } else if (screen->show_help) {
                screen->show_help = false;
+               screen->need_redraw = true;
                cui_show_help(screen->cui, _("Retrieve Config"),
                        &add_url_help_text);
 
-       } else if (handled) {
-               wrefresh(screen->scr.main_ncw);
+       } else if (handled && (screen->cui->current == scr)) {
+               pad_refresh(screen);
        }
 }
 
+static int screen_process_form(struct add_url_screen *screen)
+{
+       char *url;
+       int rc;
+
+       url = widget_textbox_get_value(screen->widgets.url_f);
+       if (!url || !strlen(url))
+               return 0;
+
+       /* Once we have all the info we need, tell the server */
+       rc = cui_send_url(screen->cui, url);
+
+       if (rc)
+               pb_log("cui_send_retreive failed!\n");
+       else
+               pb_debug("add_url url sent!\n");
+       return 0;
+}
+
 static int add_url_screen_post(struct nc_scr *scr)
 {
        struct add_url_screen *screen = add_url_screen_from_scr(scr);
+
+       if (screen->exit)
+               screen->on_exit(screen->cui);
+
        widgetset_post(screen->widgetset);
        nc_scr_frame_draw(scr);
-       redrawwin(scr->main_ncw);
+       if (screen->need_redraw) {
+               redrawwin(scr->main_ncw);
+               screen->need_redraw = false;
+       }
        wrefresh(screen->scr.main_ncw);
+       pad_refresh(screen);
        return 0;
 }
 
@@ -123,34 +166,29 @@ struct nc_scr *add_url_screen_scr(struct add_url_screen *screen)
        return &screen->scr;
 }
 
-static int screen_process_form(struct add_url_screen *screen)
+static void add_url_process_cb(struct nc_scr *scr)
 {
-       char *url;
-       int rc;
-
-       url = widget_textbox_get_value(screen->widgets.url_f);
-       if (!url || !strlen(url))
-               return 0;
-
-       /* Once we have all the info we need, tell the server */
-       rc = cui_send_url(screen->cui, url);
+       struct add_url_screen *screen = add_url_screen_from_scr(scr);
 
-       if (rc)
-               pb_log("cui_send_retreive failed!\n");
-       else
-               pb_debug("add_url url sent!\n");
-       return 0;
+       if (!screen_process_form(screen))
+               screen->exit = true;
 }
 
 static void ok_click(void *arg)
 {
        struct add_url_screen *screen = arg;
-       if (screen_process_form(screen))
-               /* errors are written to the status line, so we'll need
-                * to refresh */
-               wrefresh(screen->scr.main_ncw);
-       else
-               screen->exit = true;
+
+       if (discover_client_authenticated(screen->cui->client)) {
+               if (screen_process_form(screen))
+                       /* errors are written to the status line, so we'll need
+                        * to refresh */
+                       wrefresh(screen->scr.main_ncw);
+               else
+                       screen->exit = true;
+       } else {
+               cui_show_auth(screen->cui, screen->scr.main_ncw, false,
+                               add_url_process_cb);
+       }
 }
 
 static void help_click(void *arg)
@@ -189,9 +227,33 @@ static void add_url_screen_layout_widgets(struct add_url_screen *screen)
        widget_move(widget_button_base(screen->widgets.ok_b),
                y, screen->field_x);
        widget_move(widget_button_base(screen->widgets.help_b),
-               y, screen->field_x + 10);
+               y, screen->field_x + 14);
        widget_move(widget_button_base(screen->widgets.cancel_b),
-               y, screen->field_x + 20);
+               y, screen->field_x + 28);
+}
+
+static void add_url_screen_widget_focus(struct nc_widget *widget, void *arg)
+{
+       struct add_url_screen *screen = arg;
+       int w_y, w_height, w_focus, s_max, adjust;
+
+       w_height = widget_height(widget);
+       w_focus = widget_focus_y(widget);
+       w_y = widget_y(widget) + w_focus;
+       s_max = getmaxy(screen->scr.sub_ncw) - 1;
+
+       if (w_y < screen->scroll_y)
+               screen->scroll_y = w_y;
+
+       else if (w_y + screen->scroll_y + 1 > s_max) {
+               /* Fit as much of the widget into the screen as possible */
+               adjust = min(s_max - 1, w_height - w_focus);
+               if (w_y + adjust >= screen->scroll_y + s_max)
+                       screen->scroll_y = max(0, 1 + w_y + adjust - s_max);
+       } else
+               return;
+
+       pad_refresh(screen);
 }
 
 static void add_url_screen_setup_widgets(struct add_url_screen *screen)
@@ -205,25 +267,35 @@ static void add_url_screen_setup_widgets(struct add_url_screen *screen)
                        _("Configuration URL:"));
        screen->widgets.url_f = widget_new_textbox(set, 0, 0, 50, NULL);
 
-       screen->widgets.ok_b = widget_new_button(set, 0, 0, 6, _("OK"),
+       screen->widgets.ok_b = widget_new_button(set, 0, 0, 10, _("OK"),
                        ok_click, screen);
-       screen->widgets.help_b = widget_new_button(set, 0, 0, 6, _("Help"),
+       screen->widgets.help_b = widget_new_button(set, 0, 0, 10, _("Help"),
                        help_click, screen);
-       screen->widgets.cancel_b = widget_new_button(set, 0, 0, 6, _("Cancel"),
+       screen->widgets.cancel_b = widget_new_button(set, 0, 0, 10, _("Cancel"),
                        cancel_click, screen);
 }
 
+static int add_url_screen_destroy(void *arg)
+{
+       struct add_url_screen *screen = arg;
+       if (screen->pad)
+               delwin(screen->pad);
+       return 0;
+}
+
 struct add_url_screen *add_url_screen_init(struct cui *cui,
                void (*on_exit)(struct cui *))
 {
        struct add_url_screen *screen;
 
        screen = talloc_zero(cui, struct add_url_screen);
+       talloc_set_destructor(screen, add_url_screen_destroy);
 
        screen->cui = cui;
        screen->on_exit = on_exit;
        screen->label_x = 2;
-       screen->field_x = 22;
+       screen->field_x = 25;
+       screen->need_redraw = false;
 
        nc_scr_init(&screen->scr, pb_add_url_screen_sig, 0,
                cui, add_url_screen_process_key,
@@ -237,8 +309,11 @@ struct add_url_screen *add_url_screen_init(struct cui *cui,
                        _("tab=next, shift+tab=previous, x=exit, h=help"));
        nc_scr_frame_draw(&screen->scr);
 
+       screen->pad = newpad(LINES, COLS);
        screen->widgetset = widgetset_create(screen, screen->scr.main_ncw,
-                       NULL);
+                       screen->pad);
+       widgetset_set_widget_focus(screen->widgetset,
+                       add_url_screen_widget_focus, screen);
 
        add_url_screen_setup_widgets(screen);
        add_url_screen_layout_widgets(screen);