comparison src/utilops.c @ 1:b3e0e515fabf

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