386d813264af64e25a257b3a30b5db33f2061744
[petitboot] / ui / ncurses / nc-add-url.c
1 /*
2  *  Copyright (C) 2013 IBM Corporation
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; version 2 of the License.
7  *
8  *  This program is distributed in the hope that it will be useful,
9  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  *  GNU General Public License for more details.
12  *
13  *  You should have received a copy of the GNU General Public License
14  *  along with this program; if not, write to the Free Software
15  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16  */
17
18 #if defined(HAVE_CONFIG_H)
19 #include "config.h"
20 #endif
21
22 #include <errno.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include <talloc/talloc.h>
27 #include <types/types.h>
28 #include <i18n/i18n.h>
29 #include <log/log.h>
30
31 #include "nc-cui.h"
32 #include "nc-add-url.h"
33 #include "nc-widgets.h"
34
35 #define N_FIELDS        5
36
37 extern const struct help_text add_url_help_text;
38
39 struct add_url_screen {
40         struct nc_scr           scr;
41         struct cui              *cui;
42         struct nc_widgetset     *widgetset;
43
44         bool                    exit;
45         bool                    show_help;
46         void                    (*on_exit)(struct cui *);
47
48         int                     label_x;
49         int                     field_x;
50
51         struct {
52                 struct nc_widget_textbox        *url_f;
53                 struct nc_widget_label          *url_l;
54
55                 struct nc_widget_button         *ok_b;
56                 struct nc_widget_button         *help_b;
57                 struct nc_widget_button         *cancel_b;
58         } widgets;
59 };
60
61 static struct add_url_screen *add_url_screen_from_scr(struct nc_scr *scr)
62 {
63         struct add_url_screen *add_url_screen;
64
65         assert(scr->sig == pb_add_url_screen_sig);
66         add_url_screen = (struct add_url_screen *)
67                 ((char *)scr - (size_t)&((struct add_url_screen *)0)->scr);
68         assert(add_url_screen->scr.sig == pb_add_url_screen_sig);
69         return add_url_screen;
70 }
71
72 static void add_url_screen_process_key(struct nc_scr *scr, int key)
73 {
74         struct add_url_screen *screen = add_url_screen_from_scr(scr);
75         bool handled;
76
77         handled = widgetset_process_key(screen->widgetset, key);
78
79         if (!handled) {
80                 switch (key) {
81                 case 'x':
82                 case 27: /* esc */
83                         screen->exit = true;
84                         break;
85                 case 'h':
86                         screen->show_help = true;
87                         break;
88                 }
89         }
90
91         if (screen->exit) {
92                 screen->on_exit(screen->cui);
93
94         } else if (screen->show_help) {
95                 screen->show_help = false;
96                 cui_show_help(screen->cui, _("Retrieve Config"),
97                         &add_url_help_text);
98
99         } else if (handled) {
100                 wrefresh(screen->scr.main_ncw);
101         }
102 }
103
104 static int add_url_screen_post(struct nc_scr *scr)
105 {
106         struct add_url_screen *screen = add_url_screen_from_scr(scr);
107         widgetset_post(screen->widgetset);
108         nc_scr_frame_draw(scr);
109         redrawwin(scr->main_ncw);
110         wrefresh(screen->scr.main_ncw);
111         return 0;
112 }
113
114 static int add_url_screen_unpost(struct nc_scr *scr)
115 {
116         struct add_url_screen *screen = add_url_screen_from_scr(scr);
117         widgetset_unpost(screen->widgetset);
118         return 0;
119 }
120
121 struct nc_scr *add_url_screen_scr(struct add_url_screen *screen)
122 {
123         return &screen->scr;
124 }
125
126 static int screen_process_form(struct add_url_screen *screen)
127 {
128         char *url;
129         int rc;
130
131         url = widget_textbox_get_value(screen->widgets.url_f);
132         if (!url || !strlen(url))
133                 return 0;
134
135         /* Once we have all the info we need, tell the server */
136         rc = cui_send_url(screen->cui, url);
137
138         if (rc)
139                 pb_log("cui_send_retreive failed!\n");
140         else
141                 pb_debug("add_url url sent!\n");
142         return 0;
143 }
144
145 static void ok_click(void *arg)
146 {
147         struct add_url_screen *screen = arg;
148         if (screen_process_form(screen))
149                 /* errors are written to the status line, so we'll need
150                  * to refresh */
151                 wrefresh(screen->scr.main_ncw);
152         else
153                 screen->exit = true;
154 }
155
156 static void help_click(void *arg)
157 {
158         struct add_url_screen *screen = arg;
159         screen->show_help = true;
160 }
161
162 static void cancel_click(void *arg)
163 {
164         struct add_url_screen *screen = arg;
165         screen->exit = true;
166 }
167
168 static int layout_pair(struct add_url_screen *screen, int y,
169         struct nc_widget_label *label,
170         struct nc_widget *field)
171 {
172         struct nc_widget *label_w = widget_label_base(label);
173         widget_move(label_w, y, screen->label_x);
174         widget_move(field, y, screen->field_x);
175         return max(widget_height(label_w), widget_height(field));
176 }
177
178 static void add_url_screen_layout_widgets(struct add_url_screen *screen)
179 {
180         int y = 2;
181
182         /* url field */
183         y += layout_pair(screen, y, screen->widgets.url_l,
184                          widget_textbox_base(screen->widgets.url_f));
185
186         /* ok, help, cancel */
187         y += 1;
188
189         widget_move(widget_button_base(screen->widgets.ok_b),
190                 y, screen->field_x);
191         widget_move(widget_button_base(screen->widgets.help_b),
192                 y, screen->field_x + 10);
193         widget_move(widget_button_base(screen->widgets.cancel_b),
194                 y, screen->field_x + 24);
195 }
196
197 static void add_url_screen_setup_widgets(struct add_url_screen *screen)
198 {
199         struct nc_widgetset *set = screen->widgetset;
200
201         build_assert(sizeof(screen->widgets) / sizeof(struct widget *)
202                         == N_FIELDS);
203
204         screen->widgets.url_l = widget_new_label(set, 0, 0,
205                         _("Configuration URL:"));
206         screen->widgets.url_f = widget_new_textbox(set, 0, 0, 50, NULL);
207
208         screen->widgets.ok_b = widget_new_button(set, 0, 0, 6, _("OK"),
209                         ok_click, screen);
210         screen->widgets.help_b = widget_new_button(set, 0, 0, 10, _("Help"),
211                         help_click, screen);
212         screen->widgets.cancel_b = widget_new_button(set, 0, 0, 10, _("Cancel"),
213                         cancel_click, screen);
214 }
215
216 struct add_url_screen *add_url_screen_init(struct cui *cui,
217                 void (*on_exit)(struct cui *))
218 {
219         struct add_url_screen *screen;
220
221         screen = talloc_zero(cui, struct add_url_screen);
222
223         screen->cui = cui;
224         screen->on_exit = on_exit;
225         screen->label_x = 2;
226         screen->field_x = 25;
227
228         nc_scr_init(&screen->scr, pb_add_url_screen_sig, 0,
229                 cui, add_url_screen_process_key,
230                 add_url_screen_post, add_url_screen_unpost,
231                 NULL);
232
233         screen->scr.frame.ltitle = talloc_strdup(screen,
234                         _("Petitboot Config Retrieval"));
235         screen->scr.frame.rtitle = NULL;
236         screen->scr.frame.help = talloc_strdup(screen,
237                         _("tab=next, shift+tab=previous, x=exit, h=help"));
238         nc_scr_frame_draw(&screen->scr);
239
240         screen->widgetset = widgetset_create(screen, screen->scr.main_ncw,
241                         NULL);
242
243         add_url_screen_setup_widgets(screen);
244         add_url_screen_layout_widgets(screen);
245
246         return screen;
247 }
248