source: mainline/uspace/app/nav/copy.c

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

Copy files (Navigator and command line).

TODO Overwrite query, new I/O error types.

  • Property mode set to 100644
File size: 6.3 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 Copy Files.
34 */
35
36#include <fmgt.h>
37#include <stdlib.h>
38#include <str_error.h>
39#include <ui/fixed.h>
40#include <ui/filelist.h>
41#include <ui/msgdialog.h>
42#include <ui/resource.h>
43#include <ui/ui.h>
44#include <ui/window.h>
45#include <stdbool.h>
46#include <str.h>
47#include "copy.h"
48#include "dlg/progress.h"
49#include "dlg/copydlg.h"
50#include "menu.h"
51#include "nav.h"
52#include "types/copy.h"
53#include "panel.h"
54
55static void copy_bok(copy_dlg_t *, void *);
56static void copy_bcancel(copy_dlg_t *, void *);
57static void copy_close(copy_dlg_t *, void *);
58
59static copy_dlg_cb_t copy_cb = {
60 .bok = copy_bok,
61 .bcancel = copy_bcancel,
62 .close = copy_close
63};
64
65static bool copy_abort_query(void *);
66static void copy_progress(void *, fmgt_progress_t *);
67
68static fmgt_cb_t copy_fmgt_cb = {
69 .abort_query = copy_abort_query,
70 .io_error_query = navigator_io_error_query,
71 .progress = copy_progress,
72};
73
74/** Open Copy dialog.
75 *
76 * @param navigator Navigator
77 * @param flist File list
78 */
79void navigator_copy_dlg(navigator_t *navigator, fmgt_flist_t *flist)
80{
81 copy_dlg_t *dlg;
82 panel_t *dpanel;
83 char *dest;
84 errno_t rc;
85
86 /* Get destination panel. */
87 dpanel = navigator_get_inactive_panel(navigator);
88 if (dpanel == NULL) {
89 /* out of memory */
90 return;
91 }
92
93 /* Get destination path from destination panel. */
94 dest = panel_get_dir(dpanel);
95 if (dest == NULL) {
96 /* out of memory */
97 return;
98 }
99
100 rc = copy_dlg_create(navigator->ui, flist, dest, &dlg);
101 if (rc != EOK) {
102 free(dest);
103 return;
104 }
105
106 copy_dlg_set_cb(dlg, &copy_cb, (void *)navigator);
107 free(dest);
108}
109
110/** Copy worker function.
111 *
112 * @param arg Argument (navigator_copy_job_t)
113 */
114static void copy_wfunc(void *arg)
115{
116 fmgt_t *fmgt = NULL;
117 navigator_copy_job_t *job = (navigator_copy_job_t *)arg;
118 char *msg = NULL;
119 navigator_t *nav = job->navigator;
120 ui_msg_dialog_t *dialog = NULL;
121 ui_msg_dialog_params_t params;
122 errno_t rc;
123 int rv;
124
125 rc = fmgt_create(&fmgt);
126 if (rc != EOK) {
127 /* out of memory */
128 return;
129 }
130
131 fmgt_set_cb(fmgt, &copy_fmgt_cb, (void *)nav);
132 fmgt_set_init_update(fmgt, true);
133
134 rc = fmgt_copy(fmgt, job->flist, job->dest);
135 if (rc != EOK) {
136 rv = asprintf(&msg, "Error copying file(s) (%s).",
137 str_error(rc));
138 if (rv < 0)
139 return;
140 goto error;
141 }
142
143 fmgt_destroy(fmgt);
144 ui_lock(nav->ui);
145 progress_dlg_destroy(nav->progress_dlg);
146 navigator_refresh_panels(nav);
147 ui_unlock(nav->ui);
148 fmgt_flist_destroy(job->flist);
149 free(job);
150 return;
151error:
152 fmgt_destroy(fmgt);
153 ui_lock(nav->ui);
154 progress_dlg_destroy(nav->progress_dlg);
155 navigator_refresh_panels(nav);
156 ui_msg_dialog_params_init(&params);
157 params.caption = "Error";
158 params.text = msg;
159 (void) ui_msg_dialog_create(nav->ui, &params, &dialog);
160 ui_unlock(nav->ui);
161 free(msg);
162}
163
164/** Copy dialog confirmed.
165 *
166 * @param dlg Copy dialog
167 * @param arg Argument (navigator_t *)
168 */
169static void copy_bok(copy_dlg_t *dlg, void *arg)
170{
171 navigator_t *nav = (navigator_t *)arg;
172 ui_msg_dialog_t *dialog = NULL;
173 navigator_copy_job_t *job;
174 ui_msg_dialog_params_t params;
175 progress_dlg_params_t pd_params;
176 char *msg = NULL;
177 errno_t rc;
178
179 job = calloc(1, sizeof(navigator_copy_job_t));
180 if (job == NULL)
181 return;
182
183 job->navigator = nav;
184 job->flist = dlg->flist;
185 job->dest = str_dup(ui_entry_get_text(dlg->edest));
186 if (job->dest == NULL) {
187 free(job);
188 return;
189 }
190
191 copy_dlg_destroy(dlg);
192 dlg->flist = NULL;
193
194 progress_dlg_params_init(&pd_params);
195 pd_params.caption = "Copying";
196
197 rc = progress_dlg_create(nav->ui, &pd_params, &nav->progress_dlg);
198 if (rc != EOK) {
199 msg = str_dup("Out of memory.");
200 if (msg == NULL)
201 return;
202 goto error;
203 }
204
205 progress_dlg_set_cb(nav->progress_dlg, &navigator_progress_cb,
206 (void *)nav);
207
208 rc = navigator_worker_start(nav, copy_wfunc, (void *)job);
209 if (rc != EOK) {
210 msg = str_dup("Out of memory.");
211 if (msg == NULL)
212 return;
213 goto error;
214 }
215
216 return;
217error:
218 ui_msg_dialog_params_init(&params);
219 params.caption = "Error";
220 params.text = msg;
221 (void) ui_msg_dialog_create(nav->ui, &params, &dialog);
222 free(msg);
223}
224
225/** New file dialog cancelled.
226 *
227 * @param dlg New file dialog
228 * @param arg Argument (navigator_t *)
229 */
230static void copy_bcancel(copy_dlg_t *dlg, void *arg)
231{
232 (void)arg;
233 copy_dlg_destroy(dlg);
234}
235
236/** New file dialog closed.
237 *
238 * @param dlg New file dialog
239 * @param arg Argument (navigator_t *)
240 */
241static void copy_close(copy_dlg_t *dlg, void *arg)
242{
243 (void)arg;
244 copy_dlg_destroy(dlg);
245}
246
247/** New file abort query.
248 *
249 * @param arg Argument (navigator_t *)
250 * @return @c true iff abort is requested
251 */
252static bool copy_abort_query(void *arg)
253{
254 navigator_t *nav = (navigator_t *)arg;
255
256 return nav->abort_op;
257}
258
259/** New file progress update.
260 *
261 * @param arg Argument (navigator_t *)
262 * @param progress Progress update
263 */
264static void copy_progress(void *arg, fmgt_progress_t *progress)
265{
266 navigator_t *nav = (navigator_t *)arg;
267
268 progress_dlg_set_progress(nav->progress_dlg, progress);
269}
270
271/** @}
272 */
Note: See TracBrowser for help on using the repository browser.