source: mainline/uspace/app/nav/dlg/ioerrdlg.c@ bb4d0b5

Last change on this file since bb4d0b5 was bb4d0b5, checked in by Jiri Svoboda <jiri@…>, 3 weeks ago

Allow user to decide whether to retry or abort when I/O error occurs.

  • Property mode set to 100644
File size: 8.5 KB
Line 
1/*
2 * Copyright (c) 2025 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup nav
30 * @{
31 */
32/**
33 * @file I/O Error Dialog
34 */
35
36#include <errno.h>
37#include <fmgt.h>
38#include <mem.h>
39#include <stdbool.h>
40#include <stdlib.h>
41#include <ui/fixed.h>
42#include <ui/label.h>
43#include <ui/pbutton.h>
44#include <ui/resource.h>
45#include <ui/ui.h>
46#include <ui/window.h>
47#include "ioerrdlg.h"
48
49static void io_err_dlg_wnd_close(ui_window_t *, void *);
50static void io_err_dlg_wnd_kbd(ui_window_t *, void *, kbd_event_t *);
51
52ui_window_cb_t io_err_dlg_wnd_cb = {
53 .close = io_err_dlg_wnd_close,
54 .kbd = io_err_dlg_wnd_kbd
55};
56
57static void io_err_dlg_babort_clicked(ui_pbutton_t *, void *);
58static void io_err_dlg_bretry_clicked(ui_pbutton_t *, void *);
59
60ui_pbutton_cb_t io_err_dlg_babort_cb = {
61 .clicked = io_err_dlg_babort_clicked
62};
63
64ui_pbutton_cb_t io_err_dlg_bretry_cb = {
65 .clicked = io_err_dlg_bretry_clicked
66};
67
68/** Initialize I/O error dialog parameters structure.
69 *
70 * I/O error parameters structure must always be initialized using
71 * this function first.
72 *
73 * @param params I/O error dialog parameters structure
74 */
75void io_err_dlg_params_init(io_err_dlg_params_t *params)
76{
77 memset(params, 0, sizeof(io_err_dlg_params_t));
78 params->text1 = "";
79 params->text2 = "";
80}
81
82/** Create I/O error dialog.
83 *
84 * @param ui User interface
85 * @param params Dialog parameters
86 * @param rdialog Place to store pointer to new dialog
87 * @return EOK on success or an error code
88 */
89errno_t io_err_dlg_create(ui_t *ui, io_err_dlg_params_t *params,
90 io_err_dlg_t **rdialog)
91{
92 errno_t rc;
93 io_err_dlg_t *dialog;
94 ui_window_t *window = NULL;
95 ui_wnd_params_t wparams;
96 ui_fixed_t *fixed = NULL;
97 ui_label_t *label = NULL;
98 ui_pbutton_t *babort = NULL;
99 ui_pbutton_t *bretry = NULL;
100 gfx_rect_t rect;
101 ui_resource_t *ui_res;
102 char *name = NULL;
103
104 dialog = calloc(1, sizeof(io_err_dlg_t));
105 if (dialog == NULL) {
106 rc = ENOMEM;
107 goto error;
108 }
109
110 ui_wnd_params_init(&wparams);
111 wparams.caption = "I/O Error";
112
113 /* FIXME: Auto layout */
114 if (ui_is_textmode(ui)) {
115 wparams.rect.p0.x = 0;
116 wparams.rect.p0.y = 0;
117 wparams.rect.p1.x = 60;
118 wparams.rect.p1.y = 9;
119 } else {
120 wparams.rect.p0.x = 0;
121 wparams.rect.p0.y = 0;
122 wparams.rect.p1.x = 300;
123 wparams.rect.p1.y = 155;
124 }
125
126 rc = ui_window_create(ui, &wparams, &window);
127 if (rc != EOK)
128 goto error;
129
130 ui_window_set_cb(window, &io_err_dlg_wnd_cb, dialog);
131
132 ui_res = ui_window_get_res(window);
133
134 rc = ui_fixed_create(&fixed);
135 if (rc != EOK)
136 goto error;
137
138 rc = ui_label_create(ui_res, params->text1, &label);
139 if (rc != EOK)
140 goto error;
141
142 /* FIXME: Auto layout */
143 if (ui_is_textmode(ui)) {
144 rect.p0.x = 3;
145 rect.p0.y = 2;
146 rect.p1.x = 57;
147 rect.p1.y = 3;
148 } else {
149 rect.p0.x = 10;
150 rect.p0.y = 35;
151 rect.p1.x = 190;
152 rect.p1.y = 50;
153 }
154
155 ui_label_set_rect(label, &rect);
156 ui_label_set_halign(label, gfx_halign_center);
157
158 rc = ui_fixed_add(fixed, ui_label_ctl(label));
159 if (rc != EOK)
160 goto error;
161
162 label = NULL;
163
164 rc = ui_label_create(ui_res, params->text2, &label);
165 if (rc != EOK)
166 goto error;
167
168 /* FIXME: Auto layout */
169 if (ui_is_textmode(ui)) {
170 rect.p0.x = 3;
171 rect.p0.y = 4;
172 rect.p1.x = 57;
173 rect.p1.y = 5;
174 } else {
175 rect.p0.x = 10;
176 rect.p0.y = 35;
177 rect.p1.x = 190;
178 rect.p1.y = 50;
179 }
180
181 ui_label_set_rect(label, &rect);
182 ui_label_set_halign(label, gfx_halign_center);
183
184 rc = ui_fixed_add(fixed, ui_label_ctl(label));
185 if (rc != EOK)
186 goto error;
187
188 rc = ui_pbutton_create(ui_res, "Abort", &babort);
189 if (rc != EOK)
190 goto error;
191
192 ui_pbutton_set_cb(babort, &io_err_dlg_babort_cb, dialog);
193
194 /* FIXME: Auto layout */
195 if (ui_is_textmode(ui)) {
196 rect.p0.x = 20;
197 rect.p0.y = 6;
198 rect.p1.x = 30;
199 rect.p1.y = 7;
200 } else {
201 rect.p0.x = 55;
202 rect.p0.y = 120;
203 rect.p1.x = 145;
204 rect.p1.y = 148;
205 }
206
207 ui_pbutton_set_rect(babort, &rect);
208
209 ui_pbutton_set_default(babort, true);
210
211 rc = ui_fixed_add(fixed, ui_pbutton_ctl(babort));
212 if (rc != EOK)
213 goto error;
214
215 dialog->babort = babort;
216 babort = NULL;
217
218 rc = ui_pbutton_create(ui_res, "Retry", &bretry);
219 if (rc != EOK)
220 goto error;
221
222 ui_pbutton_set_cb(bretry, &io_err_dlg_bretry_cb, dialog);
223
224 /* FIXME: Auto layout */
225 if (ui_is_textmode(ui)) {
226 rect.p0.x = 32;
227 rect.p0.y = 6;
228 rect.p1.x = 42;
229 rect.p1.y = 7;
230 } else {
231 rect.p0.x = 155;
232 rect.p0.y = 120;
233 rect.p1.x = 245;
234 rect.p1.y = 148;
235 }
236
237 ui_pbutton_set_rect(bretry, &rect);
238
239 rc = ui_fixed_add(fixed, ui_pbutton_ctl(bretry));
240 if (rc != EOK)
241 goto error;
242
243 dialog->bretry = bretry;
244 bretry = NULL;
245
246 ui_window_add(window, ui_fixed_ctl(fixed));
247 fixed = NULL;
248
249 rc = ui_window_paint(window);
250 if (rc != EOK)
251 goto error;
252
253 dialog->window = window;
254 *rdialog = dialog;
255 return EOK;
256error:
257 if (name != NULL)
258 free(name);
259 if (babort != NULL)
260 ui_pbutton_destroy(babort);
261 if (bretry != NULL)
262 ui_pbutton_destroy(bretry);
263 if (label != NULL)
264 ui_label_destroy(label);
265 if (fixed != NULL)
266 ui_fixed_destroy(fixed);
267 if (window != NULL)
268 ui_window_destroy(window);
269 if (dialog != NULL)
270 free(dialog);
271 return rc;
272}
273
274/** Destroy prompt dialog.
275 *
276 * @param dialog Prompt dialog or @c NULL
277 */
278void io_err_dlg_destroy(io_err_dlg_t *dialog)
279{
280 if (dialog == NULL)
281 return;
282
283 ui_window_destroy(dialog->window);
284 free(dialog);
285}
286
287/** Set mesage dialog callback.
288 *
289 * @param dialog Prompt dialog
290 * @param cb Prompt dialog callbacks
291 * @param arg Callback argument
292 */
293void io_err_dlg_set_cb(io_err_dlg_t *dialog, io_err_dlg_cb_t *cb,
294 void *arg)
295{
296 dialog->cb = cb;
297 dialog->arg = arg;
298}
299
300/** Prompt dialog window close handler.
301 *
302 * @param window Window
303 * @param arg Argument (io_err_dlg_t *)
304 */
305static void io_err_dlg_wnd_close(ui_window_t *window, void *arg)
306{
307 io_err_dlg_t *dialog = (io_err_dlg_t *) arg;
308
309 (void)window;
310 if (dialog->cb != NULL && dialog->cb->close != NULL) {
311 dialog->cb->close(dialog, dialog->arg);
312 }
313}
314
315/** Prompt dialog window keyboard event handler.
316 *
317 * @param window Window
318 * @param arg Argument (io_err_dlg_t *)
319 * @param event Keyboard event
320 */
321static void io_err_dlg_wnd_kbd(ui_window_t *window, void *arg,
322 kbd_event_t *event)
323{
324 io_err_dlg_t *dialog = (io_err_dlg_t *) arg;
325
326 if (event->type == KEY_PRESS &&
327 (event->mods & (KM_CTRL | KM_SHIFT | KM_ALT)) == 0) {
328 if (event->key == KC_ENTER) {
329 /* Confirm */
330 if (dialog->cb != NULL && dialog->cb->babort != NULL) {
331 dialog->cb->babort(dialog, dialog->arg);
332 return;
333 }
334 } else if (event->key == KC_ESCAPE) {
335 /* Cancel */
336 if (dialog->cb != NULL && dialog->cb->bretry != NULL) {
337 dialog->cb->bretry(dialog, dialog->arg);
338 return;
339 }
340 }
341 }
342
343 ui_window_def_kbd(window, event);
344}
345
346/** Prompt dialog OK button click handler.
347 *
348 * @param pbutton Push button
349 * @param arg Argument (io_err_dlg_t *)
350 */
351static void io_err_dlg_babort_clicked(ui_pbutton_t *pbutton, void *arg)
352{
353 io_err_dlg_t *dialog = (io_err_dlg_t *) arg;
354
355 if (dialog->cb != NULL && dialog->cb->babort != NULL) {
356 dialog->cb->babort(dialog, dialog->arg);
357 }
358}
359
360/** Prompt dialog cancel button click handler.
361 *
362 * @param pbutton Push button
363 * @param arg Argument (io_err_dlg_t *)
364 */
365static void io_err_dlg_bretry_clicked(ui_pbutton_t *pbutton, void *arg)
366{
367 io_err_dlg_t *dialog = (io_err_dlg_t *) arg;
368
369 (void)pbutton;
370 if (dialog->cb != NULL && dialog->cb->bretry != NULL) {
371 dialog->cb->bretry(dialog, dialog->arg);
372 }
373}
374
375/** @}
376 */
Note: See TracBrowser for help on using the repository browser.