1
|
1 /*
|
|
2 * GQview image viewer
|
3
|
3 * (C)2000 John Ellis
|
1
|
4 *
|
|
5 * Author: John Ellis
|
|
6 *
|
|
7 */
|
|
8
|
|
9 #include "gqview.h"
|
|
10
|
|
11 enum {
|
|
12 DIALOG_NEW_DIR,
|
|
13 DIALOG_COPY,
|
|
14 DIALOG_MOVE,
|
|
15 DIALOG_DELETE,
|
|
16 DIALOG_RENAME
|
|
17 };
|
|
18
|
|
19 typedef struct _FileDataMult FileDataMult;
|
|
20 struct _FileDataMult
|
|
21 {
|
|
22 gint confirm_all;
|
|
23 gint confirmed;
|
|
24 gint skip;
|
|
25 GList *source_list;
|
|
26 GList *source_next;
|
|
27 gchar *dest_base;
|
|
28 gchar *source;
|
|
29 gchar *dest;
|
|
30 gint copy;
|
|
31 };
|
|
32
|
|
33 typedef struct _FileDataSingle FileDataSingle;
|
|
34 struct _FileDataSingle
|
|
35 {
|
|
36 gint confirmed;
|
|
37 gchar *source;
|
|
38 gchar *dest;
|
|
39 gint copy;
|
|
40 };
|
|
41
|
|
42 static FileDataMult *file_data_multiple_new(GList *source_list, gchar *dest, gint copy);
|
|
43 static void file_data_multiple_free(FileDataMult *fdm);
|
|
44 static void file_util_move_multiple(FileDataMult *fdm);
|
|
45 static void file_util_move_multiple_ok_cb(GtkWidget *widget, gpointer data);
|
|
46 static void file_util_move_multiple_all_cb(GtkWidget *widget, gpointer data);
|
|
47 static void file_util_move_multiple_skip_cb(GtkWidget *widget, gpointer data);
|
|
48 static void file_util_move_multiple_cancel_cb(GtkWidget *widget, gpointer data);
|
|
49 static void file_util_move_multiple(FileDataMult *fdm);
|
|
50
|
|
51 static FileDataSingle *file_data_single_new(gchar *source, gchar *dest, gint copy);
|
|
52 static void file_data_single_free(FileDataSingle *fds);
|
|
53 static void file_util_move_single_ok_cb(GtkWidget *widget, gpointer data);
|
|
54 static void file_util_move_single(FileDataSingle *fds);
|
|
55 static void file_util_move_single_cancel_cb(GtkWidget *widget, gpointer data);
|
|
56 static void file_util_move_do(FileDialog *fd);
|
|
57 static void file_util_move_check(FileDialog *fd);
|
|
58 static void file_util_move_cb(GtkWidget *widget, gpointer data);
|
|
59 static void file_util_move_enter_cb(gchar *path, gpointer data);
|
|
60 static void file_util_move_completion_sync_cb(gchar *path, gpointer data);
|
|
61 static void real_file_util_move(gchar *source_path, GList *source_list, gchar *dest_path, gint copy);
|
|
62
|
|
63 static void file_util_delete_multiple_ok_cb(GtkWidget *w, gpointer data);
|
|
64 static void file_util_delete_multiple_cancel_cb(GtkWidget *w, gpointer data);
|
|
65 static void file_util_delete_multiple(GList *source_list);
|
|
66 static void file_util_delete_ok_cb(GtkWidget *w, gpointer data);
|
|
67 static void file_util_delete_cancel_cb(GtkWidget *w, gpointer data);
|
|
68 static void file_util_delete_single(gchar *path);
|
|
69
|
|
70 static void file_util_rename_multiple_ok_cb(GtkWidget *w, gpointer data);
|
|
71 static void file_util_rename_multiple_cancel_cb(GtkWidget *w, gpointer data);
|
|
72 static void file_util_rename_multiple(FileDialog *fd);
|
|
73 static void file_util_rename_multiple_cb(GtkWidget *w, gpointer data);
|
|
74 static void file_util_rename_multiple_select_cb(GtkWidget *clist,
|
|
75 gint row, gint column, GdkEventButton *bevent, gpointer data);
|
|
76 static void file_util_rename_multiple_do(GList *source_list);
|
|
77
|
|
78 static void file_util_rename_single_ok_cb(GtkWidget *w, gpointer data);
|
|
79 static void file_util_rename_single_cancel_cb(GtkWidget *w, gpointer data);
|
|
80 static void file_util_rename_single(FileDataSingle *fds);
|
|
81 static void file_util_rename_single_cb(GtkWidget *w, gpointer data);
|
|
82 static void file_util_rename_single_do(gchar *source_path);
|
|
83
|
|
84 static void file_util_create_dir_do(gchar *source, gchar *path);
|
|
85 static void file_util_create_dir_cb(GtkWidget *w, gpointer data);
|
|
86
|
|
87 /*
|
|
88 *--------------------------------------------------------------------------
|
|
89 * Move and Copy routines
|
|
90 *--------------------------------------------------------------------------
|
|
91 */
|
|
92
|
|
93 /*
|
|
94 * Multi file move
|
|
95 */
|
|
96
|
|
97 static FileDataMult *file_data_multiple_new(GList *source_list, gchar *dest, gint copy)
|
|
98 {
|
|
99 FileDataMult *fdm = g_new0(FileDataMult, 1);
|
|
100 fdm->confirm_all = FALSE;
|
|
101 fdm->confirmed = FALSE;
|
|
102 fdm->skip = FALSE;
|
|
103 fdm->source_list = source_list;
|
|
104 fdm->source_next = fdm->source_list;
|
|
105 fdm->dest_base = g_strdup(dest);
|
|
106 fdm->source = NULL;
|
|
107 fdm->dest = NULL;
|
|
108 fdm->copy = copy;
|
|
109 return fdm;
|
|
110 }
|
|
111
|
|
112 static void file_data_multiple_free(FileDataMult *fdm)
|
|
113 {
|
|
114 free_selected_list(fdm->source_list);
|
|
115 g_free(fdm->dest_base);
|
|
116 g_free(fdm->dest);
|
|
117 g_free(fdm);
|
|
118 }
|
|
119
|
|
120 static void file_util_move_multiple_ok_cb(GtkWidget *widget, gpointer data)
|
|
121 {
|
|
122 FileDataMult *fdm = data;
|
|
123 fdm->confirmed = TRUE;
|
|
124 file_util_move_multiple(fdm);
|
|
125 }
|
|
126
|
|
127 static void file_util_move_multiple_all_cb(GtkWidget *widget, gpointer data)
|
|
128 {
|
|
129 FileDataMult *fdm = data;
|
|
130 fdm->confirm_all = TRUE;
|
|
131 file_util_move_multiple(fdm);
|
|
132 }
|
|
133
|
|
134 static void file_util_move_multiple_skip_cb(GtkWidget *widget, gpointer data)
|
|
135 {
|
|
136 FileDataMult *fdm = data;
|
|
137 fdm->skip = TRUE;
|
|
138 file_util_move_multiple(fdm);
|
|
139 }
|
|
140
|
|
141 static void file_util_move_multiple_cancel_cb(GtkWidget *widget, gpointer data)
|
|
142 {
|
|
143 FileDataMult *fdm = data;
|
|
144 file_data_multiple_free(fdm);
|
|
145 }
|
|
146
|
|
147 static void file_util_move_multiple(FileDataMult *fdm)
|
|
148 {
|
|
149 while (fdm->dest || fdm->source_next)
|
|
150 {
|
|
151 if (!fdm->dest)
|
|
152 {
|
|
153 GList *work = fdm->source_next;
|
|
154 fdm->source = work->data;
|
|
155 fdm->dest = g_strconcat(fdm->dest_base, "/", filename_from_path(fdm->source), NULL);
|
|
156 fdm->source_next = work->next;
|
|
157 }
|
|
158
|
3
|
159 if (fdm->dest && fdm->source && strcmp(fdm->dest, fdm->source) == 0)
|
|
160 {
|
|
161 ConfirmDialog *cd;
|
|
162 gchar *title;
|
|
163 gchar *text;
|
|
164 if (fdm->copy)
|
|
165 {
|
|
166 title = _("Source to copy matches destination");
|
|
167 text = g_strdup_printf(_("Unable to copy file:\n%s\nto itself."), fdm->dest);
|
|
168 }
|
|
169 else
|
|
170 {
|
|
171 title = _("Source to move matches destination");
|
|
172 text = g_strdup_printf(_("Unable to move file:\n%s\nto itself."), fdm->dest);
|
|
173 }
|
|
174 cd = confirm_dialog_new(title, text, file_util_move_multiple_cancel_cb, fdm);
|
|
175 confirm_dialog_add(cd, _("Continue"), file_util_move_multiple_skip_cb);
|
|
176 g_free(text);
|
|
177 return;
|
|
178 }
|
|
179 else if (isfile(fdm->dest) && !fdm->confirmed && !fdm->confirm_all && !fdm->skip)
|
1
|
180 {
|
|
181 ConfirmDialog *cd;
|
|
182 gchar *text = g_strdup_printf(_("Overwrite file:\n %s\n with:\b %s"), fdm->dest, fdm->source);
|
3
|
183 cd = confirm_dialog_new_with_image(_("Overwrite file"), text,
|
|
184 fdm->dest, fdm->source,
|
|
185 file_util_move_multiple_cancel_cb, fdm);
|
1
|
186 confirm_dialog_add(cd, _("Skip"), file_util_move_multiple_skip_cb);
|
|
187 confirm_dialog_add(cd, _("Yes to all"), file_util_move_multiple_all_cb);
|
|
188 confirm_dialog_add(cd, _("Yes"), file_util_move_multiple_ok_cb);
|
|
189 g_free(text);
|
|
190 return;
|
|
191 }
|
|
192 else
|
|
193 {
|
|
194 gint success = FALSE;
|
|
195 if (fdm->skip)
|
|
196 {
|
|
197 success = TRUE;
|
|
198 fdm->skip = FALSE;
|
|
199 }
|
|
200 else
|
|
201 {
|
|
202 if (fdm->copy)
|
|
203 {
|
|
204 success = copy_file(fdm->source, fdm->dest);
|
|
205 }
|
|
206 else
|
|
207 {
|
|
208 if (move_file(fdm->source, fdm->dest))
|
|
209 {
|
|
210 success = TRUE;
|
|
211 file_is_gone(fdm->source, fdm->source_list);
|
|
212 }
|
|
213 }
|
|
214 }
|
|
215 if (!success)
|
|
216 {
|
|
217 ConfirmDialog *cd;
|
|
218 gchar *title;
|
|
219 gchar *text;
|
|
220 if (fdm->copy)
|
|
221 {
|
|
222 title = _("Error copying file");
|
|
223 text = g_strdup_printf(_("Unable to copy file:\n%sto:\n%s\n during multiple file copy."), fdm->source, fdm->dest);
|
|
224 }
|
|
225 else
|
|
226 {
|
|
227 title = _("Error moving file");
|
|
228 text = g_strdup_printf(_("Unable to move file:\n%sto:\n%s\n during multiple file move."), fdm->source, fdm->dest);
|
|
229 }
|
|
230 cd = confirm_dialog_new(title, text, file_util_move_multiple_cancel_cb, fdm);
|
|
231 confirm_dialog_add(cd, _("Continue"), file_util_move_multiple_skip_cb);
|
|
232 g_free(text);
|
|
233 return;
|
|
234 }
|
|
235 fdm->confirmed = FALSE;
|
|
236 g_free(fdm->dest);
|
|
237 fdm->dest = NULL;
|
|
238 }
|
|
239 }
|
|
240
|
|
241 file_data_multiple_free(fdm);
|
|
242 }
|
|
243
|
|
244 /*
|
|
245 * Single file move
|
|
246 */
|
|
247
|
|
248 static FileDataSingle *file_data_single_new(gchar *source, gchar *dest, gint copy)
|
|
249 {
|
|
250 FileDataSingle *fds = g_new0(FileDataSingle, 1);
|
|
251 fds->confirmed = FALSE;
|
|
252 fds->source = g_strdup(source);
|
|
253 fds->dest = g_strdup(dest);
|
|
254 fds->copy = copy;
|
|
255 return fds;
|
|
256 }
|
|
257
|
|
258 static void file_data_single_free(FileDataSingle *fds)
|
|
259 {
|
|
260 g_free(fds->source);
|
|
261 g_free(fds->dest);
|
|
262 g_free(fds);
|
|
263 }
|
|
264
|
|
265 static void file_util_move_single_ok_cb(GtkWidget *widget, gpointer data)
|
|
266 {
|
|
267 FileDataSingle *fds = data;
|
|
268 fds->confirmed = TRUE;
|
|
269 file_util_move_single(fds);
|
|
270 }
|
|
271
|
|
272 static void file_util_move_single_cancel_cb(GtkWidget *widget, gpointer data)
|
|
273 {
|
|
274 FileDataSingle *fds = data;
|
|
275 file_data_single_free(fds);
|
|
276 }
|
|
277
|
|
278 static void file_util_move_single(FileDataSingle *fds)
|
|
279 {
|
3
|
280 if (fds->dest && fds->source && strcmp(fds->dest, fds->source) == 0)
|
|
281 {
|
|
282 warning_dialog(_("Source matches destination"),
|
|
283 _("Source and destination are the same, operation cancelled."));
|
|
284 }
|
|
285 else if (isfile(fds->dest) && !fds->confirmed)
|
1
|
286 {
|
|
287 ConfirmDialog *cd;
|
|
288 gchar *text = g_strdup_printf(_("Overwrite file:\n%s\n with:\n%s"), fds->dest, fds->source);
|
3
|
289 cd = confirm_dialog_new_with_image(_("Overwrite file"), text,
|
|
290 fds->dest, fds->source,
|
|
291 file_util_move_single_cancel_cb, fds);
|
1
|
292 confirm_dialog_add(cd, _("Overwrite"), file_util_move_single_ok_cb);
|
|
293 g_free(text);
|
|
294 return;
|
|
295 }
|
|
296 else
|
|
297 {
|
|
298 gint success = FALSE;
|
|
299 if (fds->copy)
|
|
300 {
|
|
301 success = copy_file(fds->source, fds->dest);
|
|
302 }
|
|
303 else
|
|
304 {
|
|
305 if (move_file(fds->source, fds->dest))
|
|
306 {
|
|
307 success = TRUE;
|
|
308 file_is_gone(fds->source, NULL);
|
|
309 }
|
|
310 }
|
|
311 if (!success)
|
|
312 {
|
|
313 gchar *title;
|
|
314 gchar *text;
|
|
315 if (fds->copy)
|
|
316 {
|
|
317 title = _("Error copying file");
|
|
318 text = g_strdup_printf(_("Unable to copy file:\n%s\nto:\n%s"), fds->source, fds->dest);
|
|
319 }
|
|
320 else
|
|
321 {
|
|
322 title = _("Error moving file");
|
|
323 text = g_strdup_printf(_("Unable to move file:\n%s\nto:\n%s"), fds->source, fds->dest);
|
|
324 }
|
|
325 warning_dialog(title, text);
|
|
326 g_free(text);
|
|
327 }
|
|
328 }
|
3
|
329
|
|
330 file_data_single_free(fds);
|
1
|
331 }
|
|
332
|
|
333 /*
|
|
334 * file move dialog
|
|
335 */
|
|
336
|
|
337 static void file_util_move_do(FileDialog *fd)
|
|
338 {
|
|
339 tab_completion_append_to_history(fd->entry, fd->dest_path);
|
|
340 if (fd->multiple_files)
|
|
341 {
|
|
342 file_util_move_multiple(file_data_multiple_new(fd->source_list, fd->dest_path, fd->type));
|
|
343 fd->source_list = NULL;
|
|
344 }
|
|
345 else
|
|
346 {
|
|
347 if (isdir(fd->dest_path))
|
|
348 {
|
|
349 gchar *buf = g_strconcat(fd->dest_path, "/", filename_from_path(fd->source_path), NULL);
|
|
350 g_free(fd->dest_path);
|
|
351 fd->dest_path = buf;
|
|
352 }
|
|
353 file_util_move_single(file_data_single_new(fd->source_path, fd->dest_path, fd->type));
|
|
354 }
|
|
355
|
|
356 generic_dialog_close(NULL, fd);
|
|
357 }
|
|
358
|
|
359 static void file_util_move_check(FileDialog *fd)
|
|
360 {
|
|
361 g_free(fd->dest_path);
|
|
362 fd->dest_path = remove_trailing_slash(gtk_entry_get_text(GTK_ENTRY(fd->entry)));
|
|
363
|
|
364 if (fd->multiple_files && !isdir(fd->dest_path))
|
|
365 {
|
|
366 if (isfile(fd->dest_path))
|
|
367 warning_dialog(_("Invalid destination"), _("When operating with multiple files, please select\n a directory, not file."));
|
|
368 else
|
|
369 warning_dialog(_("Invalid directory"), _("Please select an existing directory"));
|
|
370 return;
|
|
371 }
|
|
372
|
|
373 file_util_move_do(fd);
|
|
374 }
|
|
375
|
|
376 static void file_util_move_cb(GtkWidget *widget, gpointer data)
|
|
377 {
|
|
378 FileDialog *fd = data;
|
|
379 file_util_move_check(fd);
|
|
380 }
|
|
381
|
|
382 static void file_util_move_enter_cb(gchar *path, gpointer data)
|
|
383 {
|
|
384 FileDialog *fd = data;
|
|
385 file_util_move_check(fd);
|
|
386 }
|
|
387
|
|
388 static void file_util_move_completion_sync_cb(gchar *path, gpointer data)
|
|
389 {
|
|
390 FileDialog *fd = data;
|
|
391 destination_widget_sync_to_entry(fd->entry);
|
|
392 }
|
|
393
|
|
394 static void real_file_util_move(gchar *source_path, GList *source_list, gchar *dest_path, gint copy)
|
|
395 {
|
|
396 FileDialog *fd;
|
|
397 gchar *path = NULL;
|
|
398 gint multiple;
|
|
399 gchar *text;
|
|
400 gchar *title;
|
|
401 gchar *op_text;
|
|
402 GtkWidget *tabcomp;
|
|
403 GtkWidget *dest;
|
|
404 gchar *last_path;
|
|
405
|
|
406 if (!source_path && !source_list) return;
|
|
407
|
|
408 if (source_path)
|
|
409 {
|
|
410 path = g_strdup(source_path);
|
|
411 multiple = FALSE;
|
|
412 }
|
|
413 else if (source_list->next)
|
|
414 {
|
|
415 multiple = TRUE;
|
|
416 }
|
|
417 else
|
|
418 {
|
|
419 path = g_strdup(source_list->data);
|
|
420 free_selected_list(source_list);
|
|
421 source_list = NULL;
|
|
422 multiple = FALSE;
|
|
423 }
|
|
424
|
|
425 if (copy)
|
|
426 {
|
|
427 title = _("GQview - copy");
|
|
428 op_text = _("Copy");
|
|
429 if (path)
|
|
430 text = g_strdup_printf(_("Copy file:\n%s\nto:"), path);
|
|
431 else
|
|
432 text = g_strdup_printf(_("Copy multiple files from:\n%s\nto:"), dest_path);
|
|
433 }
|
|
434 else
|
|
435 {
|
|
436 title = _("GQview - move");
|
|
437 op_text = _("Move");
|
|
438 if (path)
|
|
439 text = g_strdup_printf(_("Move file:\n%s\nto:"), path);
|
|
440 else
|
|
441 text = g_strdup_printf(_("Move multiple files from:\n%s\nto:"), dest_path);
|
|
442 }
|
|
443
|
|
444 fd = generic_dialog_new(title, text, op_text, _("Cancel"),
|
|
445 file_util_move_cb, generic_dialog_close);
|
|
446
|
|
447 g_free(text);
|
|
448
|
|
449 fd->type = copy;
|
|
450 fd->source_path = path;
|
|
451 fd->source_list = source_list;
|
|
452 fd->multiple_files = multiple;
|
|
453
|
|
454 tabcomp = tab_completion_new_with_history(&fd->entry, fd->dialog, dest_path,
|
|
455 "move_copy", 32, file_util_move_enter_cb, fd);
|
|
456 last_path = tab_completion_set_to_last_history(fd->entry);
|
|
457 if (last_path)
|
|
458 {
|
|
459 fd->dest_path = g_strdup(last_path);
|
|
460 }
|
|
461 else
|
|
462 {
|
|
463 fd->dest_path = g_strdup(dest_path);
|
|
464 }
|
|
465
|
|
466 /* tabcomp = tab_completion_new(&fd->entry, fd->dialog, fd->dest_path, file_util_move_enter_cb, fd);
|
|
467 */
|
|
468 gtk_box_pack_start(GTK_BOX(fd->vbox), tabcomp, FALSE, FALSE, 0);
|
|
469 gtk_widget_show(tabcomp);
|
|
470
|
|
471 gtk_widget_grab_focus(fd->entry);
|
|
472
|
|
473 dest = destination_widget_new(fd->dest_path, fd->entry);
|
|
474
|
|
475 tab_completion_add_tab_func(fd->entry, file_util_move_completion_sync_cb, fd);
|
|
476
|
|
477 gtk_box_pack_start(GTK_BOX(fd->vbox), dest, TRUE, TRUE, 0);
|
|
478 }
|
|
479
|
|
480 void file_util_move(gchar *source_path, GList *source_list, gchar *dest_path)
|
|
481 {
|
|
482 real_file_util_move(source_path, source_list, dest_path, FALSE);
|
|
483 }
|
|
484
|
|
485 void file_util_copy(gchar *source_path, GList *source_list, gchar *dest_path)
|
|
486 {
|
|
487 real_file_util_move(source_path, source_list, dest_path, TRUE);
|
|
488 }
|
|
489
|
|
490 /*
|
|
491 *--------------------------------------------------------------------------
|
|
492 * Delete routines
|
|
493 *--------------------------------------------------------------------------
|
|
494 */
|
|
495
|
|
496 /*
|
|
497 * delete multiple files
|
|
498 */
|
|
499
|
|
500 static void file_util_delete_multiple_ok_cb(GtkWidget *w, gpointer data)
|
|
501 {
|
|
502 GList *source_list = data;
|
|
503
|
|
504 while(source_list)
|
|
505 {
|
|
506 gchar *path = source_list->data;
|
|
507 source_list = g_list_remove(source_list, path);
|
|
508 if (unlink (path) < 0)
|
|
509 {
|
|
510 ConfirmDialog *cd;
|
|
511 gchar *text;
|
|
512 if (source_list)
|
|
513 {
|
|
514 text = g_strdup_printf(_("Unable to delete file:\n %s\n Continue multiple delete operation?"), path);
|
|
515 cd = confirm_dialog_new(_("Delete failed"), text, file_util_delete_multiple_cancel_cb, source_list);
|
|
516 confirm_dialog_add(cd, _("Continue"), file_util_delete_multiple_ok_cb);
|
|
517 }
|
|
518 else
|
|
519 {
|
|
520 text = g_strdup_printf(_("Unable to delete file:\n%s"), path);
|
|
521 warning_dialog(_("Delete failed"), text);
|
|
522 }
|
|
523 g_free(text);
|
|
524 g_free(path);
|
|
525 return;
|
|
526 }
|
|
527 else
|
|
528 {
|
|
529 file_is_gone(path, source_list);
|
|
530 }
|
|
531 g_free(path);
|
|
532 }
|
|
533 }
|
|
534
|
|
535 static void file_util_delete_multiple_cancel_cb(GtkWidget *w, gpointer data)
|
|
536 {
|
|
537 GList *source_list = data;
|
|
538 free_selected_list(source_list);
|
|
539 }
|
|
540
|
|
541 static void file_util_delete_multiple(GList *source_list)
|
|
542 {
|
|
543 if (!confirm_delete)
|
|
544 {
|
|
545 file_util_delete_multiple_ok_cb(NULL, source_list);
|
|
546 }
|
|
547 else
|
|
548 {
|
|
549 ConfirmDialog *cd;
|
|
550 cd = confirm_dialog_new(_("Delete files"), _("About to delete multiple files..."), file_util_delete_multiple_cancel_cb, source_list);
|
|
551 confirm_dialog_add(cd, _("Delete"), file_util_delete_multiple_ok_cb);
|
|
552 }
|
|
553 }
|
|
554
|
|
555 /*
|
|
556 * delete single file
|
|
557 */
|
|
558
|
|
559 static void file_util_delete_ok_cb(GtkWidget *w, gpointer data)
|
|
560 {
|
|
561 gchar *path = data;
|
|
562
|
|
563 if (unlink (path) < 0)
|
|
564 {
|
|
565 gchar *text = g_strdup_printf(_("Unable to delete file:\n%s"), path);
|
|
566 warning_dialog(_("File deletion failed"), text);
|
|
567 g_free(text);
|
|
568 }
|
|
569 else
|
|
570 {
|
|
571 file_is_gone(path, NULL);
|
|
572 }
|
|
573
|
|
574 g_free(path);
|
|
575 }
|
|
576
|
|
577 static void file_util_delete_cancel_cb(GtkWidget *w, gpointer data)
|
|
578 {
|
|
579 gchar *path = data;
|
|
580 g_free(path);
|
|
581 }
|
|
582
|
|
583 static void file_util_delete_single(gchar *path)
|
|
584 {
|
|
585 gchar *buf = g_strdup(path);
|
|
586
|
|
587 if (!confirm_delete)
|
|
588 {
|
|
589 file_util_delete_ok_cb(NULL, buf);
|
|
590 }
|
|
591 else
|
|
592 {
|
|
593 ConfirmDialog *cd;
|
|
594 gchar *text = g_strdup_printf(_("About to delete the file:\n %s"), buf);
|
|
595 cd = confirm_dialog_new(_("Delete file"), text, file_util_delete_cancel_cb, buf);
|
|
596 confirm_dialog_add(cd, _("Delete"), file_util_delete_ok_cb);
|
|
597 g_free(text);
|
|
598 }
|
|
599 }
|
|
600
|
|
601 void file_util_delete(gchar *source_path, GList *source_list)
|
|
602 {
|
|
603 if (!source_path && !source_list) return;
|
|
604
|
|
605 if (source_path)
|
|
606 {
|
|
607 file_util_delete_single(source_path);
|
|
608 }
|
|
609 else if (!source_list->next)
|
|
610 {
|
|
611 file_util_delete_single(source_list->data);
|
|
612 free_selected_list(source_list);
|
|
613 }
|
|
614 else
|
|
615 {
|
|
616 file_util_delete_multiple(source_list);
|
|
617 }
|
|
618 }
|
|
619
|
|
620 /*
|
|
621 *--------------------------------------------------------------------------
|
|
622 * Rename routines
|
|
623 *--------------------------------------------------------------------------
|
|
624 */
|
|
625
|
|
626 /*
|
|
627 * rename multiple files
|
|
628 */
|
|
629
|
|
630 static void file_util_rename_multiple_ok_cb(GtkWidget *w, gpointer data)
|
|
631 {
|
|
632 FileDialog *fd = data;
|
|
633 if (!GTK_WIDGET_VISIBLE(fd->dialog)) gtk_widget_show(fd->dialog);
|
|
634 fd->type = TRUE;
|
|
635 file_util_rename_multiple(fd);
|
|
636 }
|
|
637
|
|
638 static void file_util_rename_multiple_cancel_cb(GtkWidget *w, gpointer data)
|
|
639 {
|
|
640 FileDialog *fd = data;
|
|
641 if (!GTK_WIDGET_VISIBLE(fd->dialog)) gtk_widget_show(fd->dialog);
|
|
642 return;
|
|
643 }
|
|
644
|
|
645 static void file_util_rename_multiple(FileDialog *fd)
|
|
646 {
|
|
647 if (isfile(fd->dest_path) && !fd->type)
|
|
648 {
|
|
649 ConfirmDialog *cd;
|
|
650 gchar *text = g_strdup_printf(_("Overwrite file:\n%s\nby renaming:\n%s"), fd->dest_path, fd->source_path);
|
3
|
651 cd = confirm_dialog_new_with_image(_("Overwrite file"), text,
|
|
652 fd->dest_path, fd->source_path,
|
|
653 file_util_rename_multiple_cancel_cb, fd);
|
1
|
654 confirm_dialog_add(cd, _("Overwrite"), file_util_rename_multiple_ok_cb);
|
|
655 g_free(text);
|
|
656 gtk_widget_hide(fd->dialog);
|
|
657 return;
|
|
658 }
|
|
659 else
|
|
660 {
|
|
661 if (rename (fd->source_path, fd->dest_path) < 0)
|
|
662 {
|
|
663 gchar *text = g_strdup_printf(_("Unable to rename file:\n%s\n to:\n%s"), filename_from_path(fd->source_path), filename_from_path(fd->dest_path));
|
|
664 warning_dialog(_("Error renaming file"), text);
|
|
665 g_free(text);
|
|
666 }
|
|
667 else
|
|
668 {
|
|
669 gint row;
|
|
670 gint n;
|
|
671 GtkWidget *clist;
|
|
672 gchar *path;
|
|
673
|
|
674 file_is_renamed(fd->source_path, fd->dest_path);
|
|
675
|
|
676 clist = gtk_object_get_user_data(GTK_OBJECT(fd->entry));
|
|
677 path = gtk_object_get_user_data(GTK_OBJECT(clist));
|
|
678 row = gtk_clist_find_row_from_data(GTK_CLIST(clist), path);
|
|
679
|
|
680 n = g_list_length(GTK_CLIST(clist)->row_list);
|
|
681 if (debug) printf("r=%d n=%d\n", row, n);
|
|
682 if (n - 1 > row)
|
|
683 n = row;
|
|
684 else if (n > 1)
|
|
685 n = row - 1;
|
|
686 else
|
|
687 n = -1;
|
|
688
|
|
689 if (n >= 0)
|
|
690 {
|
|
691 gtk_object_set_user_data(GTK_OBJECT(clist), NULL);
|
|
692 gtk_clist_remove(GTK_CLIST(clist), row);
|
|
693 gtk_clist_select_row(GTK_CLIST(clist), n, -1);
|
|
694 }
|
|
695 else
|
|
696 {
|
|
697 if (debug) printf("closed by #%d\n", n);
|
|
698 generic_dialog_close(NULL, fd);
|
|
699 }
|
|
700 }
|
|
701 }
|
|
702 }
|
|
703
|
|
704 static void file_util_rename_multiple_cb(GtkWidget *w, gpointer data)
|
|
705 {
|
|
706 FileDialog *fd = data;
|
|
707 gchar *base;
|
|
708 gchar *name;
|
|
709
|
|
710 name = gtk_entry_get_text(GTK_ENTRY(fd->entry));
|
|
711 base = remove_level_from_path(fd->source_path);
|
|
712 g_free(fd->dest_path);
|
|
713 fd->dest_path = g_strconcat(base, "/", name, NULL);
|
|
714 g_free(base);
|
|
715
|
|
716 if (strlen(name) == 0 || strcmp(fd->source_path, fd->dest_path) == 0)
|
|
717 {
|
|
718 return;
|
|
719 }
|
|
720
|
|
721 fd->type = FALSE;
|
|
722 file_util_rename_multiple(fd);
|
|
723 }
|
|
724
|
|
725 static void file_util_rename_multiple_select_cb(GtkWidget *clist,
|
|
726 gint row, gint column, GdkEventButton *bevent, gpointer data)
|
|
727 {
|
|
728 FileDialog *fd = data;
|
|
729 GtkWidget *label;
|
|
730 gchar *name;
|
|
731 gchar *path;
|
|
732
|
|
733 label = gtk_object_get_user_data(GTK_OBJECT(fd->dialog));
|
|
734 path = gtk_clist_get_row_data(GTK_CLIST(clist), row);
|
|
735 g_free(fd->source_path);
|
|
736 fd->source_path = g_strdup(path);
|
|
737 gtk_object_set_user_data(GTK_OBJECT(clist), path);
|
|
738 name = filename_from_path(fd->source_path);
|
|
739
|
|
740 gtk_label_set(GTK_LABEL(label), name);
|
|
741 gtk_entry_set_text(GTK_ENTRY(fd->entry), name);
|
|
742
|
|
743 gtk_widget_grab_focus(fd->entry);
|
|
744 }
|
|
745
|
|
746 static void file_util_rename_multiple_do(GList *source_list)
|
|
747 {
|
|
748 FileDialog *fd;
|
|
749 GtkWidget *scrolled;
|
|
750 GtkWidget *clist;
|
|
751 GtkWidget *label;
|
|
752 GList *work;
|
|
753
|
|
754 fd = generic_dialog_new(_("GQview - rename"), _("Rename multiple files:"), _("Rename"), _("Cancel"),
|
|
755 file_util_rename_multiple_cb, generic_dialog_close);
|
|
756
|
|
757 fd->source_path = g_strdup(source_list->data);
|
|
758 fd->dest_path = NULL;
|
|
759
|
|
760 scrolled = gtk_scrolled_window_new(NULL, NULL);
|
|
761 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
|
|
762 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
|
|
763 gtk_box_pack_start(GTK_BOX(fd->vbox), scrolled, TRUE, TRUE, 0);
|
|
764 gtk_widget_show(scrolled);
|
|
765
|
|
766 clist=gtk_clist_new (1);
|
|
767 gtk_clist_set_column_auto_resize(GTK_CLIST(clist), 0, TRUE);
|
|
768 gtk_signal_connect (GTK_OBJECT (clist), "select_row",(GtkSignalFunc) file_util_rename_multiple_select_cb, fd);
|
|
769 gtk_widget_set_usize(clist, 250, 150);
|
|
770 gtk_container_add (GTK_CONTAINER (scrolled), clist);
|
|
771 gtk_widget_show (clist);
|
|
772
|
|
773 gtk_object_set_user_data(GTK_OBJECT(clist), source_list->data);
|
|
774
|
|
775 work = source_list;
|
|
776 while(work)
|
|
777 {
|
|
778 gint row;
|
|
779 gchar *buf[2];
|
|
780 buf[0] = filename_from_path(work->data);
|
|
781 buf[1] = NULL;
|
|
782 row = gtk_clist_append(GTK_CLIST(clist), buf);
|
|
783 gtk_clist_set_row_data_full(GTK_CLIST(clist), row,
|
|
784 work->data, (GtkDestroyNotify) g_free);
|
|
785 work = work->next;
|
|
786 }
|
|
787
|
|
788 g_list_free(source_list);
|
|
789
|
|
790 label = gtk_label_new(_("Rename:"));
|
|
791 gtk_box_pack_start(GTK_BOX(fd->vbox), label, FALSE, FALSE, 0);
|
|
792 gtk_widget_show(label);
|
|
793
|
|
794 label = gtk_label_new(filename_from_path(fd->source_path));
|
|
795 gtk_box_pack_start(GTK_BOX(fd->vbox), label, FALSE, FALSE, 0);
|
|
796 gtk_widget_show(label);
|
|
797 gtk_object_set_user_data(GTK_OBJECT(fd->dialog), label);
|
|
798
|
|
799 label = gtk_label_new(_("to:"));
|
|
800 gtk_box_pack_start(GTK_BOX(fd->vbox), label, FALSE, FALSE, 0);
|
|
801 gtk_widget_show(label);
|
|
802
|
|
803 fd->entry = gtk_entry_new();
|
|
804 gtk_entry_set_text(GTK_ENTRY(fd->entry), filename_from_path(fd->source_path));
|
|
805 gtk_box_pack_start(GTK_BOX(fd->vbox), fd->entry, FALSE, FALSE, 0);
|
|
806 gtk_widget_grab_focus(fd->entry);
|
|
807 gtk_widget_show(fd->entry);
|
|
808
|
|
809 gtk_object_set_user_data(GTK_OBJECT(fd->entry), clist);
|
|
810 }
|
|
811
|
|
812 /*
|
|
813 * rename single file
|
|
814 */
|
|
815
|
|
816 static void file_util_rename_single_ok_cb(GtkWidget *w, gpointer data)
|
|
817 {
|
|
818 FileDataSingle *fds = data;
|
|
819 fds->confirmed = TRUE;
|
|
820 file_util_rename_single(fds);
|
|
821 }
|
|
822
|
|
823 static void file_util_rename_single_cancel_cb(GtkWidget *w, gpointer data)
|
|
824 {
|
|
825 FileDataSingle *fds = data;
|
|
826 file_data_single_free(fds);
|
|
827 }
|
|
828
|
|
829 static void file_util_rename_single(FileDataSingle *fds)
|
|
830 {
|
|
831 if (isfile(fds->dest) && !fds->confirmed)
|
|
832 {
|
|
833 ConfirmDialog *cd;
|
3
|
834 gchar *text = g_strdup_printf(_("Overwrite file:\n%s\nby renaming:\n%s"), fds->dest,fds->source);
|
|
835 cd = confirm_dialog_new_with_image(_("Overwrite file"), text,
|
|
836 fds->dest, fds->source,
|
|
837 file_util_rename_single_cancel_cb, fds);
|
1
|
838 confirm_dialog_add(cd, _("Overwrite"), file_util_rename_single_ok_cb);
|
|
839 g_free(text);
|
|
840 return;
|
|
841 }
|
|
842 else
|
|
843 {
|
|
844 if (rename (fds->source, fds->dest) < 0)
|
|
845 {
|
|
846 gchar *text = g_strdup_printf(_("Unable to rename file:\n%s\nto:\n%s"), filename_from_path(fds->source), filename_from_path(fds->dest));
|
|
847 warning_dialog(_("Error renaming file"), text);
|
|
848 g_free(text);
|
|
849 }
|
|
850 else
|
|
851 {
|
|
852 file_is_renamed(fds->source, fds->dest);
|
|
853 }
|
|
854 }
|
|
855 file_data_single_free(fds);
|
|
856 }
|
|
857
|
|
858 static void file_util_rename_single_cb(GtkWidget *w, gpointer data)
|
|
859 {
|
|
860 FileDialog *fd = data;
|
|
861 gchar *name = gtk_entry_get_text(GTK_ENTRY(fd->entry));
|
|
862 gchar *buf = g_strconcat(fd->dest_path, "/", name, NULL);
|
|
863
|
|
864 if (strlen(name) == 0 || strcmp(fd->source_path, buf) == 0)
|
|
865 {
|
|
866 g_free(buf);
|
|
867 return;
|
|
868 }
|
|
869
|
|
870 g_free(fd->dest_path);
|
|
871 fd->dest_path = buf;
|
|
872
|
|
873 file_util_rename_single(file_data_single_new(fd->source_path, fd->dest_path, fd->type));
|
|
874
|
|
875 generic_dialog_close(NULL, fd);
|
|
876 }
|
|
877
|
|
878 static void file_util_rename_single_do(gchar *source_path)
|
|
879 {
|
|
880 FileDialog *fd;
|
|
881 gchar *text;
|
|
882 gchar *name = filename_from_path(source_path);
|
|
883
|
|
884 text = g_strdup_printf(_("Rename file:\n%s\nto:"), name);
|
|
885 fd = generic_dialog_new(_("GQview - rename"), text, _("Rename"), _("Cancel"),
|
|
886 file_util_rename_single_cb, generic_dialog_close);
|
|
887 g_free(text);
|
|
888
|
|
889 fd->source_path = g_strdup(source_path);
|
|
890 fd->dest_path = remove_level_from_path(source_path);
|
|
891
|
|
892 fd->entry = gtk_entry_new();
|
|
893 gtk_entry_set_text(GTK_ENTRY(fd->entry), name);
|
|
894 gtk_box_pack_start(GTK_BOX(fd->vbox), fd->entry, FALSE, FALSE, 0);
|
|
895 gtk_widget_grab_focus(fd->entry);
|
|
896 gtk_widget_show(fd->entry);
|
|
897 }
|
|
898
|
|
899 void file_util_rename(gchar *source_path, GList *source_list)
|
|
900 {
|
|
901 if (!source_path && !source_list) return;
|
|
902
|
|
903 if (source_path)
|
|
904 {
|
|
905 file_util_rename_single_do(source_path);
|
|
906 }
|
|
907 else if (!source_list->next)
|
|
908 {
|
|
909 file_util_rename_single_do(source_list->data);
|
|
910 free_selected_list(source_list);
|
|
911 }
|
|
912 else
|
|
913 {
|
|
914 file_util_rename_multiple_do(source_list);
|
|
915 }
|
|
916 }
|
|
917
|
|
918 /*
|
|
919 *--------------------------------------------------------------------------
|
|
920 * Create directory routines
|
|
921 *--------------------------------------------------------------------------
|
|
922 */
|
|
923
|
|
924 static void file_util_create_dir_do(gchar *source, gchar *path)
|
|
925 {
|
|
926 if (isfile(path))
|
|
927 {
|
|
928 gchar *text = g_strdup_printf(_("The path:\n%s\nalready exists as a file."), filename_from_path(path));
|
|
929 warning_dialog(_("Could not create directory"), text);
|
|
930 g_free(text);
|
|
931 }
|
|
932 else if (isdir(path))
|
|
933 {
|
|
934 gchar *text = g_strdup_printf(_("The directory:\n%s\nalready exists."), filename_from_path(path));
|
|
935 warning_dialog(_("Directory exists"), text);
|
|
936 g_free(text);
|
|
937 }
|
|
938 else
|
|
939 {
|
|
940 if (mkdir (path, 0755) < 0)
|
|
941 {
|
|
942 gchar *text = g_strdup_printf(_("Unable to create directory:\n%s"), filename_from_path(path));
|
|
943 warning_dialog(_("Error creating directory"), text);
|
|
944 g_free(text);
|
|
945 }
|
|
946 else
|
|
947 {
|
|
948 if (strcmp(source, current_path) == 0)
|
|
949 {
|
|
950 gchar *buf = g_strdup(current_path);
|
|
951 filelist_change_to(buf);
|
|
952 g_free(buf);
|
|
953 }
|
|
954 }
|
|
955 }
|
|
956 }
|
|
957
|
|
958 static void file_util_create_dir_cb(GtkWidget *w, gpointer data)
|
|
959 {
|
|
960 FileDialog *fd = data;
|
|
961 gchar *name = gtk_entry_get_text(GTK_ENTRY(fd->entry));
|
|
962
|
|
963 if (strlen(name) == 0) return;
|
|
964
|
|
965 g_free(fd->dest_path);
|
|
966 fd->dest_path = g_strconcat(fd->source_path, "/", name, NULL);
|
|
967
|
|
968 file_util_create_dir_do(fd->source_path, fd->dest_path);
|
|
969
|
|
970 generic_dialog_close(NULL, fd);
|
|
971 }
|
|
972
|
|
973 void file_util_create_dir(gchar *path)
|
|
974 {
|
|
975 FileDialog *fd;
|
|
976 gchar *text;
|
|
977 gchar *name;
|
|
978
|
|
979 if (!isdir(path)) return;
|
|
980 name = filename_from_path(path);
|
|
981
|
|
982 text = g_strdup_printf(_("Create directory in:\n%s\nnamed:"), path);
|
|
983 fd = generic_dialog_new(_("GQview - new directory"), text, _("Create"), _("Cancel"),
|
|
984 file_util_create_dir_cb, generic_dialog_close);
|
|
985 g_free(text);
|
|
986
|
|
987 fd->source_path = g_strdup(path);
|
|
988 fd->dest_path = NULL;
|
|
989
|
|
990 fd->entry = gtk_entry_new();
|
|
991 gtk_box_pack_start(GTK_BOX(fd->vbox), fd->entry, FALSE, FALSE, 0);
|
|
992 gtk_widget_grab_focus(fd->entry);
|
|
993 gtk_widget_show(fd->entry);
|
|
994 }
|
|
995
|