source: mainline/uspace/app/nav/newfile.c@ c3db721

Last change on this file since c3db721 was c3db721, checked in by Jiri Svoboda <jiri@…>, 2 months ago

Allow aborting file management operation.

  • Property mode set to 100644
File size: 6.6 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 Navigator New File.
34 */
35
36#include <capa.h>
37#include <fmgt.h>
38#include <stdlib.h>
39#include <str_error.h>
40#include <ui/fixed.h>
41#include <ui/filelist.h>
42#include <ui/msgdialog.h>
43#include <ui/resource.h>
44#include <ui/ui.h>
45#include <ui/window.h>
46#include <stdbool.h>
47#include <str.h>
48#include "dlg/newfiledlg.h"
49#include "dlg/progress.h"
50#include "menu.h"
51#include "newfile.h"
52#include "nav.h"
53#include "types/newfile.h"
54
55static void new_file_bok(new_file_dlg_t *, void *, const char *, const char *,
56 bool);
57static void new_file_bcancel(new_file_dlg_t *, void *);
58static void new_file_close(new_file_dlg_t *, void *);
59
60static new_file_dlg_cb_t new_file_cb = {
61 .bok = new_file_bok,
62 .bcancel = new_file_bcancel,
63 .close = new_file_close
64};
65
66static bool new_file_abort_query(void *);
67static void new_file_progress(void *, fmgt_progress_t *);
68
69static fmgt_cb_t new_file_fmgt_cb = {
70 .abort_query = new_file_abort_query,
71 .progress = new_file_progress,
72};
73
74/** Open New File dialog.
75 *
76 * @param navigator Navigator
77 */
78void navigator_new_file_dlg(navigator_t *navigator)
79{
80 new_file_dlg_t *dlg;
81
82 new_file_dlg_create(navigator->ui, &dlg);
83 new_file_dlg_set_cb(dlg, &new_file_cb, (void *)navigator);
84}
85
86/** New file worker function.
87 *
88 * @param arg Argument (navigator_new_file_job_t)
89 */
90static void new_file_wfunc(void *arg)
91{
92 fmgt_t *fmgt = NULL;
93 navigator_new_file_job_t *job = (navigator_new_file_job_t *)arg;
94 char *msg = NULL;
95 navigator_t *nav = job->navigator;
96 ui_msg_dialog_t *dialog = NULL;
97 ui_msg_dialog_params_t params;
98 errno_t rc;
99 int rv;
100
101 rc = fmgt_create(&fmgt);
102 if (rc != EOK) {
103 /* out of memory */
104 return;
105 }
106
107 fmgt_set_cb(fmgt, &new_file_fmgt_cb, (void *)nav);
108 fmgt_set_init_update(fmgt, true);
109
110 rc = fmgt_new_file(fmgt, job->fname, job->nbytes,
111 job->sparse ? nf_sparse : nf_none);
112 if (rc != EOK) {
113 rv = asprintf(&msg, "Error creating file (%s).",
114 str_error(rc));
115 if (rv < 0)
116 return;
117 goto error;
118 }
119
120 fmgt_destroy(fmgt);
121 ui_lock(nav->ui);
122 progress_dlg_destroy(nav->progress_dlg);
123 navigator_refresh_panels(nav);
124 ui_unlock(nav->ui);
125 free(job);
126 return;
127error:
128 fmgt_destroy(fmgt);
129 ui_lock(nav->ui);
130 progress_dlg_destroy(nav->progress_dlg);
131 navigator_refresh_panels(nav);
132 ui_msg_dialog_params_init(&params);
133 params.caption = "Error";
134 params.text = msg;
135 (void) ui_msg_dialog_create(nav->ui, &params, &dialog);
136 ui_unlock(nav->ui);
137 free(msg);
138}
139
140/** New file dialog confirmed.
141 *
142 * @param dlg New file dialog
143 * @param arg Argument (navigator_t *)
144 * @param fname New file name
145 * @param fsize New file size
146 * @param sparse @c true to create a sparse file
147 */
148static void new_file_bok(new_file_dlg_t *dlg, void *arg, const char *fname,
149 const char *fsize, bool sparse)
150{
151 navigator_t *nav = (navigator_t *)arg;
152 ui_msg_dialog_t *dialog = NULL;
153 navigator_new_file_job_t *job;
154 ui_msg_dialog_params_t params;
155 progress_dlg_params_t pd_params;
156 capa_spec_t fcap;
157 char *msg = NULL;
158 errno_t rc;
159 uint64_t nbytes;
160 int rv;
161
162 rc = capa_parse(fsize, &fcap);
163 if (rc != EOK) {
164 /* invalid file size */
165 return;
166 }
167
168 new_file_dlg_destroy(dlg);
169
170 rc = capa_to_blocks(&fcap, cv_nom, 1, &nbytes);
171 if (rc != EOK) {
172 rv = asprintf(&msg, "File size too large (%s).", fsize);
173 if (rv < 0)
174 return;
175 goto error;
176 }
177
178 job = calloc(1, sizeof(navigator_new_file_job_t));
179 if (job == NULL)
180 return;
181
182 job->navigator = nav;
183 job->fname = fname;
184 job->nbytes = nbytes;
185 job->sparse = sparse;
186
187 progress_dlg_params_init(&pd_params);
188 pd_params.caption = "Creating new file";
189
190 rc = progress_dlg_create(nav->ui, &pd_params, &nav->progress_dlg);
191 if (rc != EOK) {
192 msg = str_dup("Out of memory.");
193 if (msg == NULL)
194 return;
195 goto error;
196 }
197
198 progress_dlg_set_cb(nav->progress_dlg, &navigator_progress_cb,
199 (void *)nav);
200
201 rc = navigator_worker_start(nav, new_file_wfunc, (void *)job);
202 if (rc != EOK) {
203 msg = str_dup("Out of memory.");
204 if (msg == NULL)
205 return;
206 goto error;
207 }
208
209 return;
210error:
211 ui_msg_dialog_params_init(&params);
212 params.caption = "Error";
213 params.text = msg;
214 (void) ui_msg_dialog_create(nav->ui, &params, &dialog);
215 free(msg);
216}
217
218/** New file dialog cancelled.
219 *
220 * @param dlg New file dialog
221 * @param arg Argument (navigator_t *)
222 */
223static void new_file_bcancel(new_file_dlg_t *dlg, void *arg)
224{
225 (void)arg;
226 new_file_dlg_destroy(dlg);
227}
228
229/** New file dialog closed.
230 *
231 * @param dlg New file dialog
232 * @param arg Argument (navigator_t *)
233 */
234static void new_file_close(new_file_dlg_t *dlg, void *arg)
235{
236 (void)arg;
237 new_file_dlg_destroy(dlg);
238}
239
240/** New file abort query.
241 *
242 * @param arg Argument (navigator_t *)
243 * @return @c true iff abort is requested
244 */
245static bool new_file_abort_query(void *arg)
246{
247 navigator_t *nav = (navigator_t *)arg;
248
249 return nav->abort_op;
250}
251
252/** New file progress update.
253 *
254 * @param arg Argument (navigator_t *)
255 * @param progress Progress update
256 */
257static void new_file_progress(void *arg, fmgt_progress_t *progress)
258{
259 navigator_t *nav = (navigator_t *)arg;
260 char buf[128];
261
262 snprintf(buf, sizeof(buf), "Written %s of %s (%s done).",
263 progress->curf_procb, progress->curf_totalb,
264 progress->curf_percent);
265 progress_dlg_set_curf_prog(nav->progress_dlg, buf);
266}
267
268/** @}
269 */
Note: See TracBrowser for help on using the repository browser.