Mercurial > geeqie.yaz
annotate src/utilops.c @ 34:772fe5a509b1
Thu Apr 7 08:42:54 2005 John Ellis <johne@verizon.net>
* pixbuf-renderer.c (pr_queue_to_tiles): Fix logic in test for
only_existing argument.
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
##### an offical release when making enhancements and translation updates. #####
author | gqview |
---|---|
date | Thu, 07 Apr 2005 12:50:57 +0000 |
parents | 3263965d5f9e |
children | 606fcf461a68 |
rev | line source |
---|---|
1 | 1 /* |
9 | 2 * GQview |
3 * (C) 2004 John Ellis | |
1 | 4 * |
5 * Author: John Ellis | |
6 * | |
9 | 7 * This software is released under the GNU General Public License (GNU GPL). |
8 * Please read the included file COPYING for more information. | |
9 * This software comes with no warranty of any kind, use at your own risk! | |
1 | 10 */ |
11 | |
9 | 12 |
1 | 13 #include "gqview.h" |
9 | 14 #include "utilops.h" |
15 | |
16 | |
17 #include "cache_maint.h" | |
18 #include "collect.h" | |
19 #include "dupe.h" | |
20 #include "filelist.h" | |
21 #include "image.h" | |
22 #include "img-view.h" | |
23 #include "layout.h" | |
24 #include "search.h" | |
25 #include "ui_bookmark.h" | |
26 #include "ui_fileops.h" | |
27 #include "ui_misc.h" | |
28 #include "ui_tabcomp.h" | |
29 | |
30 | |
31 /* | |
32 *-------------------------------------------------------------------------- | |
33 * call these when names change, files move, deleted, etc. | |
34 * so that any open windows are also updated | |
35 *-------------------------------------------------------------------------- | |
36 */ | |
37 | |
38 void file_maint_renamed(const gchar *source, const gchar *dest) | |
39 { | |
40 cache_maint_moved(source, dest); | |
41 collection_maint_renamed(source, dest); | |
42 | |
43 layout_maint_renamed(source, dest); | |
44 view_window_maint_moved(source, dest); | |
45 dupe_maint_renamed(source, dest); | |
46 search_maint_renamed(source, dest); | |
47 } | |
48 | |
49 /* under most cases ignore_list should be NULL */ | |
50 void file_maint_removed(const gchar *path, GList *ignore_list) | |
51 { | |
52 layout_maint_removed(path, ignore_list); | |
53 view_window_maint_removed(path, ignore_list); | |
54 dupe_maint_removed(path); | |
55 search_maint_removed(path); | |
56 | |
57 collection_maint_removed(path); | |
58 cache_maint_removed(path); | |
59 } | |
60 | |
61 /* special case for correct main window behavior */ | |
62 void file_maint_moved(const gchar *source, const gchar *dest, GList *ignore_list) | |
63 { | |
64 cache_maint_moved(source, dest); | |
65 collection_maint_renamed(source, dest); | |
66 | |
67 layout_maint_moved(source, dest, ignore_list); | |
68 view_window_maint_moved(source, dest); | |
69 dupe_maint_renamed(source, dest); | |
70 search_maint_renamed(source, dest); | |
71 } | |
72 | |
73 void file_maint_copied(const gchar *source, const gchar *dest) | |
74 { | |
75 cache_maint_copied(source, dest); | |
76 } | |
77 | |
78 /* | |
79 *-------------------------------------------------------------------------- | |
80 * The file manipulation dialogs | |
81 *-------------------------------------------------------------------------- | |
82 */ | |
83 | |
1 | 84 |
85 enum { | |
86 DIALOG_NEW_DIR, | |
87 DIALOG_COPY, | |
88 DIALOG_MOVE, | |
89 DIALOG_DELETE, | |
90 DIALOG_RENAME | |
91 }; | |
92 | |
93 typedef struct _FileDataMult FileDataMult; | |
94 struct _FileDataMult | |
95 { | |
96 gint confirm_all; | |
97 gint confirmed; | |
98 gint skip; | |
99 GList *source_list; | |
100 GList *source_next; | |
101 gchar *dest_base; | |
102 gchar *source; | |
103 gchar *dest; | |
104 gint copy; | |
9 | 105 |
106 gint rename; | |
107 gint rename_auto; | |
108 gint rename_all; | |
109 | |
110 GtkWidget *rename_box; | |
111 GtkWidget *rename_entry; | |
112 GtkWidget *rename_auto_box; | |
113 | |
114 GtkWidget *yes_all_button; | |
1 | 115 }; |
116 | |
117 typedef struct _FileDataSingle FileDataSingle; | |
118 struct _FileDataSingle | |
119 { | |
120 gint confirmed; | |
121 gchar *source; | |
122 gchar *dest; | |
123 gint copy; | |
9 | 124 |
125 gint rename; | |
126 gint rename_auto; | |
127 | |
128 GtkWidget *rename_box; | |
129 GtkWidget *rename_entry; | |
130 GtkWidget *rename_auto_box; | |
1 | 131 }; |
132 | |
9 | 133 /* |
134 *-------------------------------------------------------------------------- | |
135 * Adds 1 or 2 images (if 2, side by side) to a GenericDialog | |
136 *-------------------------------------------------------------------------- | |
137 */ | |
138 | |
139 #define DIALOG_DEF_IMAGE_DIM_X 200 | |
140 #define DIALOG_DEF_IMAGE_DIM_Y 150 | |
141 | |
142 static void generic_dialog_add_image(GenericDialog *gd, const gchar *path1, const gchar *header1, | |
143 const gchar *path2, const gchar *header2, | |
144 gint show_filename) | |
145 { | |
146 ImageWindow *imd; | |
147 GtkWidget *hbox = NULL; | |
148 GtkWidget *vbox; | |
149 GtkWidget *label = NULL; | |
150 | |
151 if (path2) | |
152 { | |
153 hbox = pref_box_new(gd->vbox, TRUE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE); | |
154 } | |
155 | |
156 /* image 1 */ | |
157 | |
158 vbox = gtk_vbox_new(FALSE, PREF_PAD_GAP); | |
159 if (hbox) | |
160 { | |
161 GtkWidget *sep; | |
162 | |
163 gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0); | |
164 | |
165 sep = gtk_vseparator_new(); | |
166 gtk_box_pack_start(GTK_BOX(hbox), sep, FALSE, FALSE, 0); | |
167 gtk_widget_show(sep); | |
168 } | |
169 else | |
170 { | |
171 gtk_box_pack_start(GTK_BOX(gd->vbox), vbox, TRUE, TRUE, PREF_PAD_GAP); | |
172 } | |
173 gtk_widget_show(vbox); | |
174 | |
175 if (header1) | |
176 { | |
177 GtkWidget *head; | |
178 | |
179 head = pref_label_new(vbox, header1); | |
180 pref_label_bold(head, TRUE, FALSE); | |
181 gtk_misc_set_alignment(GTK_MISC(head), 0.0, 0.5); | |
182 } | |
183 | |
184 imd = image_new(FALSE); | |
185 gtk_widget_set_size_request(imd->widget, DIALOG_DEF_IMAGE_DIM_X, DIALOG_DEF_IMAGE_DIM_Y); | |
186 gtk_box_pack_start(GTK_BOX(vbox), imd->widget, TRUE, TRUE, 0); | |
187 image_change_path(imd, path1, 0.0); | |
188 gtk_widget_show(imd->widget); | |
189 | |
190 if (show_filename) | |
191 { | |
192 label = pref_label_new(vbox, (path1 == NULL) ? "" : filename_from_path(path1)); | |
193 } | |
194 | |
195 /* only the first image is stored (for use in gd_image_set) */ | |
196 g_object_set_data(G_OBJECT(gd->dialog), "img_image", imd); | |
197 g_object_set_data(G_OBJECT(gd->dialog), "img_label", label); | |
198 | |
199 | |
200 /* image 2 */ | |
201 | |
202 if (hbox && path2) | |
203 { | |
204 vbox = pref_box_new(hbox, TRUE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP); | |
205 | |
206 if (header2) | |
207 { | |
208 GtkWidget *head; | |
209 | |
210 head = pref_label_new(vbox, header2); | |
211 pref_label_bold(head, TRUE, FALSE); | |
212 gtk_misc_set_alignment(GTK_MISC(head), 0.0, 0.5); | |
213 } | |
214 | |
215 imd = image_new(FALSE); | |
216 gtk_widget_set_size_request(imd->widget, DIALOG_DEF_IMAGE_DIM_X, DIALOG_DEF_IMAGE_DIM_Y); | |
217 gtk_box_pack_start(GTK_BOX(vbox), imd->widget, TRUE, TRUE, 0); | |
218 image_change_path(imd, path2, 0.0); | |
219 gtk_widget_show(imd->widget); | |
220 | |
221 pref_label_new(vbox, filename_from_path(path2)); | |
222 } | |
223 } | |
224 | |
225 static void generic_dialog_image_set(GenericDialog *gd, const gchar *path) | |
226 { | |
227 ImageWindow *imd; | |
228 GtkWidget *label; | |
229 | |
230 imd = g_object_get_data(G_OBJECT(gd->dialog), "img_image"); | |
231 label = g_object_get_data(G_OBJECT(gd->dialog), "img_label"); | |
232 | |
233 if (!imd) return; | |
234 | |
235 image_change_path(imd, path, 0.0); | |
236 if (label) gtk_label_set_text(GTK_LABEL(label), filename_from_path(path)); | |
237 } | |
238 | |
239 /* | |
240 *-------------------------------------------------------------------------- | |
241 * Wrappers to aid in setting additional dialog properties (unde mouse, etc.) | |
242 *-------------------------------------------------------------------------- | |
243 */ | |
244 | |
245 GenericDialog *file_util_gen_dlg(const gchar *title, | |
246 const gchar *wmclass, const gchar *wmsubclass, | |
247 GtkWidget *parent, gint auto_close, | |
248 void (*cancel_cb)(GenericDialog *, gpointer), gpointer data) | |
249 { | |
250 GenericDialog *gd; | |
251 | |
252 gd = generic_dialog_new(title, wmclass, wmsubclass, parent, auto_close, cancel_cb, data); | |
253 if (place_dialogs_under_mouse) | |
254 { | |
255 gtk_window_set_position(GTK_WINDOW(gd->dialog), GTK_WIN_POS_MOUSE); | |
256 } | |
257 | |
258 return gd; | |
259 } | |
260 | |
261 FileDialog *file_util_file_dlg(const gchar *title, | |
262 const gchar *wmclass, const gchar *wmsubclass, | |
263 GtkWidget *parent, | |
264 void (*cancel_cb)(FileDialog *, gpointer), gpointer data) | |
265 { | |
266 FileDialog *fd; | |
267 | |
268 fd = file_dialog_new(title, wmclass, wmsubclass, parent, cancel_cb, data); | |
269 if (place_dialogs_under_mouse) | |
270 { | |
271 gtk_window_set_position(GTK_WINDOW(GENERIC_DIALOG(fd)->dialog), GTK_WIN_POS_MOUSE); | |
272 } | |
273 | |
274 return fd; | |
275 } | |
276 | |
277 /* this warning dialog is copied from SLIK's ui_utildg.c, | |
278 * because it does not have a mouse center option, | |
279 * and we must center it before show, implement it here. | |
280 */ | |
281 static void file_util_warning_dialog_ok_cb(GenericDialog *gd, gpointer data) | |
282 { | |
283 /* no op */ | |
284 } | |
285 | |
286 GenericDialog *file_util_warning_dialog(const gchar *heading, const gchar *message, | |
287 const gchar *icon_stock_id, GtkWidget *parent) | |
288 { | |
289 GenericDialog *gd; | |
290 | |
291 gd = file_util_gen_dlg(heading, "GQview", "warning", parent, TRUE, NULL, NULL); | |
292 generic_dialog_add_message(gd, icon_stock_id, heading, message); | |
293 generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, file_util_warning_dialog_ok_cb, TRUE); | |
294 if (place_dialogs_under_mouse) | |
295 { | |
296 gtk_window_set_position(GTK_WINDOW(gd->dialog), GTK_WIN_POS_MOUSE); | |
297 } | |
298 gtk_widget_show(gd->dialog); | |
299 | |
300 return gd; | |
301 } | |
1 | 302 |
303 /* | |
304 *-------------------------------------------------------------------------- | |
305 * Move and Copy routines | |
306 *-------------------------------------------------------------------------- | |
307 */ | |
308 | |
309 /* | |
310 * Multi file move | |
311 */ | |
312 | |
9 | 313 static FileDataMult *file_data_multiple_new(GList *source_list, const gchar *dest, gint copy) |
1 | 314 { |
315 FileDataMult *fdm = g_new0(FileDataMult, 1); | |
316 fdm->confirm_all = FALSE; | |
317 fdm->confirmed = FALSE; | |
318 fdm->skip = FALSE; | |
319 fdm->source_list = source_list; | |
320 fdm->source_next = fdm->source_list; | |
321 fdm->dest_base = g_strdup(dest); | |
322 fdm->source = NULL; | |
323 fdm->dest = NULL; | |
324 fdm->copy = copy; | |
325 return fdm; | |
326 } | |
327 | |
328 static void file_data_multiple_free(FileDataMult *fdm) | |
329 { | |
9 | 330 path_list_free(fdm->source_list); |
1 | 331 g_free(fdm->dest_base); |
332 g_free(fdm->dest); | |
333 g_free(fdm); | |
334 } | |
335 | |
9 | 336 static void file_util_move_multiple(FileDataMult *fdm); |
337 | |
338 static void file_util_move_multiple_ok_cb(GenericDialog *gd, gpointer data) | |
1 | 339 { |
340 FileDataMult *fdm = data; | |
9 | 341 |
1 | 342 fdm->confirmed = TRUE; |
9 | 343 |
344 if (fdm->rename_auto) | |
345 { | |
346 gchar *buf; | |
347 | |
348 buf = unique_filename_simple(fdm->dest); | |
349 if (buf) | |
350 { | |
351 g_free(fdm->dest); | |
352 fdm->dest = buf; | |
353 } | |
354 else | |
355 { | |
356 /* unique failed? well, return to the overwrite prompt :( */ | |
357 fdm->confirmed = FALSE; | |
358 } | |
359 } | |
360 else if (fdm->rename) | |
361 { | |
362 const gchar *name; | |
363 | |
364 name = gtk_entry_get_text(GTK_ENTRY(fdm->rename_entry)); | |
365 if (strlen(name) == 0 || | |
366 strcmp(name, filename_from_path(fdm->source)) == 0) | |
367 { | |
368 fdm->confirmed = FALSE; | |
369 } | |
370 else | |
371 { | |
372 g_free(fdm->dest); | |
373 fdm->dest = concat_dir_and_file(fdm->dest_base, name); | |
374 fdm->confirmed = !isname(fdm->dest); | |
375 } | |
376 } | |
377 | |
1 | 378 file_util_move_multiple(fdm); |
379 } | |
380 | |
9 | 381 static void file_util_move_multiple_all_cb(GenericDialog *gd, gpointer data) |
1 | 382 { |
383 FileDataMult *fdm = data; | |
9 | 384 |
385 fdm->confirm_all = TRUE; | |
386 | |
387 if (fdm->rename_auto) fdm->rename_all = TRUE; | |
388 | |
389 file_util_move_multiple(fdm); | |
390 } | |
391 | |
392 static void file_util_move_multiple_skip_cb(GenericDialog *gd, gpointer data) | |
393 { | |
394 FileDataMult *fdm = data; | |
395 | |
396 fdm->skip = TRUE; | |
397 fdm->confirmed = TRUE; | |
398 | |
399 file_util_move_multiple(fdm); | |
400 } | |
401 | |
402 static void file_util_move_multiple_skip_all_cb(GenericDialog *gd, gpointer data) | |
403 { | |
404 FileDataMult *fdm = data; | |
405 | |
406 fdm->skip = TRUE; | |
1 | 407 fdm->confirm_all = TRUE; |
408 file_util_move_multiple(fdm); | |
409 } | |
410 | |
9 | 411 static void file_util_move_multiple_continue_cb(GenericDialog *gd, gpointer data) |
1 | 412 { |
413 FileDataMult *fdm = data; | |
9 | 414 |
415 fdm->confirmed = TRUE; | |
1 | 416 file_util_move_multiple(fdm); |
417 } | |
418 | |
9 | 419 static void file_util_move_multiple_cancel_cb(GenericDialog *gd, gpointer data) |
1 | 420 { |
421 FileDataMult *fdm = data; | |
9 | 422 |
1 | 423 file_data_multiple_free(fdm); |
424 } | |
425 | |
9 | 426 /* rename option */ |
427 | |
428 static void file_util_move_multiple_rename_auto_cb(GtkWidget *widget, gpointer data) | |
429 { | |
430 GenericDialog *gd = data; | |
431 FileDataMult *fdm; | |
432 | |
433 fdm = gd->data; | |
434 | |
435 fdm->rename_auto = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); | |
436 gtk_widget_set_sensitive(fdm->rename_box, !fdm->rename_auto); | |
437 gtk_widget_set_sensitive(fdm->rename_entry, (!fdm->rename_auto && fdm->rename)); | |
438 | |
439 if (fdm->rename_auto) | |
440 { | |
441 gchar *preview; | |
442 | |
443 preview = unique_filename_simple(fdm->dest); | |
444 if (preview) gtk_entry_set_text(GTK_ENTRY(fdm->rename_entry), filename_from_path(preview)); | |
445 g_free(preview); | |
446 } | |
447 | |
448 gtk_widget_set_sensitive(fdm->yes_all_button, (fdm->rename_auto || !fdm->rename)); | |
449 } | |
450 | |
451 static void file_util_move_multiple_rename_cb(GtkWidget *widget, gpointer data) | |
452 { | |
453 GenericDialog *gd = data; | |
454 FileDataMult *fdm; | |
455 | |
456 fdm = gd->data; | |
457 | |
458 fdm->rename = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); | |
459 gtk_widget_set_sensitive(fdm->rename_entry, fdm->rename); | |
460 gtk_widget_set_sensitive(fdm->yes_all_button, !fdm->rename); | |
461 | |
462 if (fdm->rename) gtk_widget_grab_focus(fdm->rename_entry); | |
463 } | |
464 | |
465 static GenericDialog *file_util_move_multiple_confirm_dialog(FileDataMult *fdm) | |
466 { | |
467 GenericDialog *gd; | |
468 GtkWidget *hbox; | |
469 | |
470 gd = file_util_gen_dlg(_("Overwrite file"), "GQview", "dlg_confirm", | |
471 NULL, TRUE, | |
472 file_util_move_multiple_cancel_cb, fdm); | |
473 | |
474 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, | |
475 _("Overwrite file?"), | |
476 _("Replace existing file with new file.")); | |
477 pref_spacer(gd->vbox, 0); | |
478 | |
479 generic_dialog_add_button(gd, GTK_STOCK_YES, _("_Overwrite"), file_util_move_multiple_ok_cb, TRUE); | |
480 fdm->yes_all_button = generic_dialog_add_button(gd, NULL, _("Overwrite _all"), | |
481 file_util_move_multiple_all_cb, FALSE); | |
482 generic_dialog_add_button(gd, GTK_STOCK_GOTO_LAST, _("S_kip all"), file_util_move_multiple_skip_all_cb, FALSE); | |
483 generic_dialog_add_button(gd, GTK_STOCK_GO_FORWARD, _("_Skip"), file_util_move_multiple_skip_cb, FALSE); | |
484 generic_dialog_add_image(gd, fdm->dest, _("Existing file"), fdm->source, _("New file"), TRUE); | |
485 | |
486 /* rename option */ | |
487 | |
488 fdm->rename = FALSE; | |
489 fdm->rename_all = FALSE; | |
490 fdm->rename_auto = FALSE; | |
491 | |
492 hbox = pref_box_new(gd->vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_GAP); | |
493 | |
494 fdm->rename_auto_box = gtk_check_button_new_with_label(_("Auto rename")); | |
495 g_signal_connect(G_OBJECT(fdm->rename_auto_box), "clicked", | |
496 G_CALLBACK(file_util_move_multiple_rename_auto_cb), gd); | |
497 gtk_box_pack_start(GTK_BOX(hbox), fdm->rename_auto_box, FALSE, FALSE, 0); | |
498 gtk_widget_show(fdm->rename_auto_box); | |
499 | |
500 hbox = pref_box_new(gd->vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_GAP); | |
501 | |
502 fdm->rename_box = gtk_check_button_new_with_label(_("Rename")); | |
503 g_signal_connect(G_OBJECT(fdm->rename_box), "clicked", | |
504 G_CALLBACK(file_util_move_multiple_rename_cb), gd); | |
505 gtk_box_pack_start(GTK_BOX(hbox), fdm->rename_box, FALSE, FALSE, 0); | |
506 gtk_widget_show(fdm->rename_box); | |
507 | |
508 fdm->rename_entry = gtk_entry_new(); | |
509 gtk_entry_set_text(GTK_ENTRY(fdm->rename_entry), filename_from_path(fdm->dest)); | |
510 gtk_widget_set_sensitive(fdm->rename_entry, FALSE); | |
511 gtk_box_pack_start(GTK_BOX(hbox), fdm->rename_entry, TRUE, TRUE, 0); | |
512 gtk_widget_show(fdm->rename_entry); | |
513 | |
514 return gd; | |
515 } | |
516 | |
1 | 517 static void file_util_move_multiple(FileDataMult *fdm) |
518 { | |
519 while (fdm->dest || fdm->source_next) | |
520 { | |
9 | 521 gint success = FALSE; |
522 gint skip_file = FALSE; | |
523 | |
1 | 524 if (!fdm->dest) |
525 { | |
526 GList *work = fdm->source_next; | |
527 fdm->source = work->data; | |
9 | 528 fdm->dest = concat_dir_and_file(fdm->dest_base, filename_from_path(fdm->source)); |
1 | 529 fdm->source_next = work->next; |
9 | 530 fdm->confirmed = FALSE; |
1 | 531 } |
532 | |
3 | 533 if (fdm->dest && fdm->source && strcmp(fdm->dest, fdm->source) == 0) |
534 { | |
9 | 535 if (!fdm->confirmed) |
3 | 536 { |
9 | 537 GenericDialog *gd; |
538 const gchar *title; | |
539 gchar *text; | |
540 | |
541 if (fdm->copy) | |
542 { | |
543 title = _("Source to copy matches destination"); | |
544 text = g_strdup_printf(_("Unable to copy file:\n%s\nto itself."), fdm->dest); | |
545 } | |
546 else | |
547 { | |
548 title = _("Source to move matches destination"); | |
549 text = g_strdup_printf(_("Unable to move file:\n%s\nto itself."), fdm->dest); | |
550 } | |
551 | |
552 gd = file_util_gen_dlg(title, "GQview", "dlg_confirm", | |
553 NULL, TRUE, | |
554 file_util_move_multiple_cancel_cb, fdm); | |
555 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_WARNING, title, text); | |
556 g_free(text); | |
557 generic_dialog_add_button(gd, GTK_STOCK_GO_FORWARD, _("Co_ntinue"), | |
558 file_util_move_multiple_continue_cb, TRUE); | |
559 | |
560 gtk_widget_show(gd->dialog); | |
561 return; | |
3 | 562 } |
9 | 563 skip_file = TRUE; |
3 | 564 } |
9 | 565 else if (isfile(fdm->dest)) |
1 | 566 { |
9 | 567 if (!fdm->confirmed && !fdm->confirm_all) |
568 { | |
569 GenericDialog *gd; | |
570 | |
571 gd = file_util_move_multiple_confirm_dialog(fdm); | |
572 gtk_widget_show(gd->dialog); | |
573 return; | |
574 } | |
575 if (fdm->skip) skip_file = TRUE; | |
576 } | |
577 | |
578 if (skip_file) | |
579 { | |
580 success = TRUE; | |
581 if (!fdm->confirm_all) fdm->skip = FALSE; | |
1 | 582 } |
583 else | |
584 { | |
9 | 585 gint try = TRUE; |
586 | |
587 if (fdm->confirm_all && fdm->rename_all && isfile(fdm->dest)) | |
1 | 588 { |
9 | 589 gchar *buf; |
590 buf = unique_filename_simple(fdm->dest); | |
591 if (buf) | |
592 { | |
593 g_free(fdm->dest); | |
594 fdm->dest = buf; | |
595 } | |
596 else | |
597 { | |
598 try = FALSE; | |
599 } | |
1 | 600 } |
9 | 601 if (try) |
1 | 602 { |
603 if (fdm->copy) | |
604 { | |
9 | 605 if (copy_file(fdm->source, fdm->dest)) |
606 { | |
607 success = TRUE; | |
608 file_maint_copied(fdm->source, fdm->dest); | |
609 } | |
1 | 610 } |
611 else | |
612 { | |
613 if (move_file(fdm->source, fdm->dest)) | |
614 { | |
615 success = TRUE; | |
9 | 616 file_maint_moved(fdm->source, fdm->dest, fdm->source_list); |
1 | 617 } |
618 } | |
619 } | |
9 | 620 } |
621 | |
622 if (!success) | |
623 { | |
624 GenericDialog *gd; | |
625 const gchar *title; | |
626 gchar *text; | |
627 | |
628 if (fdm->copy) | |
629 { | |
630 title = _("Error copying file"); | |
631 text = g_strdup_printf(_("Unable to copy file:\n%s\nto:\n%s\nduring multiple file copy."), fdm->source, fdm->dest); | |
632 } | |
633 else | |
1 | 634 { |
9 | 635 title = _("Error moving file"); |
636 text = g_strdup_printf(_("Unable to move file:\n%s\nto:\n%s\nduring multiple file move."), fdm->source, fdm->dest); | |
1 | 637 } |
9 | 638 gd = file_util_gen_dlg(title, "GQview", "dlg_confirm", |
639 NULL, TRUE, | |
640 file_util_move_multiple_cancel_cb, fdm); | |
641 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_WARNING, title, text); | |
642 g_free(text); | |
643 | |
644 generic_dialog_add_button(gd, GTK_STOCK_GO_FORWARD, _("Co_ntinue"), | |
645 file_util_move_multiple_continue_cb, TRUE); | |
646 gtk_widget_show(gd->dialog); | |
1 | 647 } |
9 | 648 |
649 g_free(fdm->dest); | |
650 fdm->dest = NULL; | |
651 | |
652 if (!success) return; | |
1 | 653 } |
654 | |
655 file_data_multiple_free(fdm); | |
656 } | |
657 | |
658 /* | |
659 * Single file move | |
660 */ | |
661 | |
9 | 662 static FileDataSingle *file_data_single_new(const gchar *source, const gchar *dest, gint copy) |
1 | 663 { |
664 FileDataSingle *fds = g_new0(FileDataSingle, 1); | |
665 fds->confirmed = FALSE; | |
666 fds->source = g_strdup(source); | |
667 fds->dest = g_strdup(dest); | |
668 fds->copy = copy; | |
669 return fds; | |
670 } | |
671 | |
672 static void file_data_single_free(FileDataSingle *fds) | |
673 { | |
674 g_free(fds->source); | |
675 g_free(fds->dest); | |
676 g_free(fds); | |
677 } | |
678 | |
9 | 679 static void file_util_move_single(FileDataSingle *fds); |
680 | |
681 static void file_util_move_single_ok_cb(GenericDialog *gd, gpointer data) | |
1 | 682 { |
683 FileDataSingle *fds = data; | |
9 | 684 |
1 | 685 fds->confirmed = TRUE; |
9 | 686 |
687 if (fds->rename_auto) | |
688 { | |
689 gchar *buf; | |
690 | |
691 buf = unique_filename_simple(fds->dest); | |
692 if (buf) | |
693 { | |
694 g_free(fds->dest); | |
695 fds->dest = buf; | |
696 } | |
697 else | |
698 { | |
699 /* unique failed? well, return to the overwrite prompt :( */ | |
700 fds->confirmed = FALSE; | |
701 } | |
702 } | |
703 else if (fds->rename) | |
704 { | |
705 const gchar *name; | |
706 | |
707 name = gtk_entry_get_text(GTK_ENTRY(fds->rename_entry)); | |
708 if (strlen(name) == 0 || | |
709 strcmp(name, filename_from_path(fds->source)) == 0) | |
710 { | |
711 fds->confirmed = FALSE; | |
712 } | |
713 else | |
714 { | |
715 gchar *base; | |
716 | |
717 base = remove_level_from_path(fds->dest); | |
718 g_free(fds->dest); | |
719 fds->dest = concat_dir_and_file(base, name); | |
720 fds->confirmed = !isname(fds->dest); | |
721 | |
722 g_free(base); | |
723 } | |
724 } | |
725 | |
1 | 726 file_util_move_single(fds); |
727 } | |
728 | |
9 | 729 static void file_util_move_single_cancel_cb(GenericDialog *gd, gpointer data) |
1 | 730 { |
731 FileDataSingle *fds = data; | |
9 | 732 |
1 | 733 file_data_single_free(fds); |
734 } | |
735 | |
9 | 736 static void file_util_move_single_rename_auto_cb(GtkWidget *widget, gpointer data) |
737 { | |
738 GenericDialog *gd = data; | |
739 FileDataSingle *fds; | |
740 | |
741 fds = gd->data; | |
742 | |
743 fds->rename_auto = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); | |
744 gtk_widget_set_sensitive(fds->rename_box, !fds->rename_auto); | |
745 gtk_widget_set_sensitive(fds->rename_entry, (!fds->rename_auto && fds->rename)); | |
746 | |
747 if (fds->rename_auto) | |
748 { | |
749 gchar *preview; | |
750 | |
751 preview = unique_filename_simple(fds->dest); | |
752 if (preview) gtk_entry_set_text(GTK_ENTRY(fds->rename_entry), filename_from_path(preview)); | |
753 g_free(preview); | |
754 } | |
755 } | |
756 | |
757 static void file_util_move_single_rename_cb(GtkWidget *widget, gpointer data) | |
758 { | |
759 GenericDialog *gd = data; | |
760 FileDataSingle *fds; | |
761 | |
762 fds = gd->data; | |
763 | |
764 fds->rename = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); | |
765 gtk_widget_set_sensitive(fds->rename_entry, fds->rename); | |
766 | |
767 if (fds->rename) gtk_widget_grab_focus(fds->rename_entry); | |
768 } | |
769 | |
1 | 770 static void file_util_move_single(FileDataSingle *fds) |
771 { | |
3 | 772 if (fds->dest && fds->source && strcmp(fds->dest, fds->source) == 0) |
773 { | |
9 | 774 file_util_warning_dialog(_("Source matches destination"), |
775 _("Source and destination are the same, operation cancelled."), | |
776 GTK_STOCK_DIALOG_INFO, NULL); | |
3 | 777 } |
778 else if (isfile(fds->dest) && !fds->confirmed) | |
1 | 779 { |
9 | 780 GenericDialog *gd; |
781 GtkWidget *hbox; | |
782 | |
783 gd = file_util_gen_dlg(_("Overwrite file"), "GQview", "dlg_confirm", | |
784 NULL, TRUE, | |
785 file_util_move_single_cancel_cb, fds); | |
786 | |
787 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, | |
788 _("Overwrite file?"), | |
789 _("Replace existing file with new file.")); | |
790 pref_spacer(gd->vbox, 0); | |
791 | |
792 generic_dialog_add_button(gd, GTK_STOCK_OK, _("_Overwrite"), file_util_move_single_ok_cb, TRUE); | |
793 generic_dialog_add_image(gd, fds->dest, _("Existing file"), fds->source, _("New file"), TRUE); | |
794 | |
795 /* rename option */ | |
796 | |
797 fds->rename = FALSE; | |
798 fds->rename_auto = FALSE; | |
799 | |
800 hbox = pref_box_new(gd->vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_GAP); | |
801 | |
802 fds->rename_auto_box = gtk_check_button_new_with_label(_("Auto rename")); | |
803 g_signal_connect(G_OBJECT(fds->rename_auto_box), "clicked", | |
804 G_CALLBACK(file_util_move_single_rename_auto_cb), gd); | |
805 gtk_box_pack_start(GTK_BOX(hbox), fds->rename_auto_box, FALSE, FALSE, 0); | |
806 gtk_widget_show(fds->rename_auto_box); | |
807 | |
808 hbox = pref_box_new(gd->vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_GAP); | |
809 | |
810 fds->rename_box = gtk_check_button_new_with_label(_("Rename")); | |
811 g_signal_connect(G_OBJECT(fds->rename_box), "clicked", | |
812 G_CALLBACK(file_util_move_single_rename_cb), gd); | |
813 gtk_box_pack_start(GTK_BOX(hbox), fds->rename_box, FALSE, FALSE, 0); | |
814 gtk_widget_show(fds->rename_box); | |
815 | |
816 fds->rename_entry = gtk_entry_new(); | |
817 gtk_entry_set_text(GTK_ENTRY(fds->rename_entry), filename_from_path(fds->dest)); | |
818 gtk_widget_set_sensitive(fds->rename_entry, FALSE); | |
819 gtk_box_pack_start(GTK_BOX(hbox), fds->rename_entry, TRUE, TRUE, 0); | |
820 gtk_widget_show(fds->rename_entry); | |
821 | |
822 gtk_widget_show(gd->dialog); | |
1 | 823 return; |
824 } | |
825 else | |
826 { | |
827 gint success = FALSE; | |
828 if (fds->copy) | |
829 { | |
9 | 830 if (copy_file(fds->source, fds->dest)) |
831 { | |
832 success = TRUE; | |
833 file_maint_copied(fds->source, fds->dest); | |
834 } | |
1 | 835 } |
836 else | |
837 { | |
838 if (move_file(fds->source, fds->dest)) | |
839 { | |
840 success = TRUE; | |
9 | 841 file_maint_moved(fds->source, fds->dest, NULL); |
1 | 842 } |
843 } | |
844 if (!success) | |
845 { | |
846 gchar *title; | |
847 gchar *text; | |
848 if (fds->copy) | |
849 { | |
850 title = _("Error copying file"); | |
851 text = g_strdup_printf(_("Unable to copy file:\n%s\nto:\n%s"), fds->source, fds->dest); | |
852 } | |
853 else | |
854 { | |
855 title = _("Error moving file"); | |
856 text = g_strdup_printf(_("Unable to move file:\n%s\nto:\n%s"), fds->source, fds->dest); | |
857 } | |
9 | 858 file_util_warning_dialog(title, text, GTK_STOCK_DIALOG_ERROR, NULL); |
1 | 859 g_free(text); |
860 } | |
861 } | |
3 | 862 |
863 file_data_single_free(fds); | |
1 | 864 } |
865 | |
866 /* | |
867 * file move dialog | |
868 */ | |
869 | |
870 static void file_util_move_do(FileDialog *fd) | |
871 { | |
9 | 872 file_dialog_sync_history(fd, TRUE); |
873 | |
1 | 874 if (fd->multiple_files) |
875 { | |
876 file_util_move_multiple(file_data_multiple_new(fd->source_list, fd->dest_path, fd->type)); | |
877 fd->source_list = NULL; | |
878 } | |
879 else | |
880 { | |
881 if (isdir(fd->dest_path)) | |
882 { | |
9 | 883 gchar *buf = concat_dir_and_file(fd->dest_path, filename_from_path(fd->source_path)); |
884 gtk_entry_set_text(GTK_ENTRY(fd->entry), buf); | |
885 g_free(buf); | |
1 | 886 } |
887 file_util_move_single(file_data_single_new(fd->source_path, fd->dest_path, fd->type)); | |
888 } | |
889 | |
9 | 890 file_dialog_close(fd); |
1 | 891 } |
892 | |
893 static void file_util_move_check(FileDialog *fd) | |
894 { | |
895 if (fd->multiple_files && !isdir(fd->dest_path)) | |
896 { | |
897 if (isfile(fd->dest_path)) | |
9 | 898 { |
899 file_util_warning_dialog(_("Invalid destination"), | |
900 _("When operating with multiple files, please select\na folder, not a file."), | |
901 GTK_STOCK_DIALOG_INFO, NULL); | |
902 } | |
1 | 903 else |
9 | 904 file_util_warning_dialog(_("Invalid folder"), |
905 _("Please select an existing folder."), | |
906 GTK_STOCK_DIALOG_INFO, NULL); | |
1 | 907 return; |
908 } | |
909 | |
910 file_util_move_do(fd); | |
911 } | |
912 | |
9 | 913 static void file_util_move_cb(FileDialog *fd, gpointer data) |
1 | 914 { |
915 file_util_move_check(fd); | |
916 } | |
917 | |
9 | 918 static void file_util_move_cancel_cb(FileDialog *fd, gpointer data) |
1 | 919 { |
9 | 920 file_dialog_close(fd); |
1 | 921 } |
922 | |
9 | 923 static void real_file_util_move(const gchar *source_path, GList *source_list, |
924 const gchar *dest_path, gint copy, GtkWidget *parent) | |
1 | 925 { |
926 FileDialog *fd; | |
9 | 927 GtkWidget *label; |
1 | 928 gchar *path = NULL; |
929 gint multiple; | |
9 | 930 const gchar *text; |
931 const gchar *title; | |
932 const gchar *op_text; | |
933 const gchar *stock_id; | |
1 | 934 |
935 if (!source_path && !source_list) return; | |
936 | |
937 if (source_path) | |
938 { | |
939 path = g_strdup(source_path); | |
940 multiple = FALSE; | |
941 } | |
942 else if (source_list->next) | |
943 { | |
944 multiple = TRUE; | |
945 } | |
946 else | |
947 { | |
948 path = g_strdup(source_list->data); | |
9 | 949 path_list_free(source_list); |
1 | 950 source_list = NULL; |
951 multiple = FALSE; | |
952 } | |
953 | |
954 if (copy) | |
955 { | |
9 | 956 title = _("Copy - GQview"); |
957 op_text = _("_Copy"); | |
1 | 958 if (path) |
9 | 959 { |
960 text = _("Copy file"); | |
961 } | |
1 | 962 else |
9 | 963 { |
964 text = _("Copy multiple files"); | |
965 } | |
966 stock_id = GTK_STOCK_COPY; | |
1 | 967 } |
968 else | |
969 { | |
9 | 970 title = _("Move - GQview"); |
971 op_text = _("_Move"); | |
1 | 972 if (path) |
9 | 973 { |
974 text = _("Move file"); | |
975 } | |
1 | 976 else |
9 | 977 { |
978 text = _("Move multiple files"); | |
979 } | |
980 stock_id = GTK_STOCK_OK; | |
1 | 981 } |
982 | |
9 | 983 fd = file_util_file_dlg(title, "GQview", "dlg_copymove", parent, |
984 file_util_move_cancel_cb, NULL); | |
985 generic_dialog_add_message(GENERIC_DIALOG(fd), NULL, text, NULL); | |
986 | |
987 if (path) | |
988 { | |
989 GtkWidget *box; | |
990 | |
991 box = pref_box_new(GENERIC_DIALOG(fd)->vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE); | |
992 pref_label_new(box, _("File name:")); | |
993 pref_label_new(box, filename_from_path(path)); | |
994 } | |
995 | |
996 label = pref_label_new(GENERIC_DIALOG(fd)->vbox, _("Choose the destination folder.")); | |
997 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); | |
998 pref_spacer(GENERIC_DIALOG(fd)->vbox, 0); | |
999 | |
1000 file_dialog_add_button(fd, stock_id, op_text, file_util_move_cb, TRUE); | |
1001 | |
1002 file_dialog_add_path_widgets(fd, NULL, dest_path, "move_copy", NULL, NULL); | |
1 | 1003 |
1004 fd->type = copy; | |
1005 fd->source_path = path; | |
1006 fd->source_list = source_list; | |
1007 fd->multiple_files = multiple; | |
1008 | |
9 | 1009 gtk_widget_show(GENERIC_DIALOG(fd)->dialog); |
1010 } | |
1011 | |
1012 void file_util_move(const gchar *source_path, GList *source_list, const gchar *dest_path, GtkWidget *parent) | |
1013 { | |
1014 real_file_util_move(source_path, source_list, dest_path, FALSE, parent); | |
1015 } | |
1016 | |
1017 void file_util_copy(const gchar *source_path, GList *source_list, const gchar *dest_path, GtkWidget *parent) | |
1018 { | |
1019 real_file_util_move(source_path, source_list, dest_path, TRUE, parent); | |
1020 } | |
1021 | |
1022 void file_util_move_simple(GList *list, const gchar *dest_path) | |
1023 { | |
1024 if (!list) return; | |
1025 if (!dest_path) | |
1026 { | |
1027 path_list_free(list); | |
1028 return; | |
1029 } | |
1030 | |
1031 if (!list->next) | |
1032 { | |
1033 const gchar *source; | |
1034 gchar *dest; | |
1035 | |
1036 source = list->data; | |
1037 dest = concat_dir_and_file(dest_path, filename_from_path(source)); | |
1038 | |
1039 file_util_move_single(file_data_single_new(source, dest, FALSE)); | |
1040 g_free(dest); | |
1041 path_list_free(list); | |
1042 return; | |
1043 } | |
1044 | |
1045 file_util_move_multiple(file_data_multiple_new(list, dest_path, FALSE)); | |
1046 } | |
1047 | |
1048 void file_util_copy_simple(GList *list, const gchar *dest_path) | |
1049 { | |
1050 if (!list) return; | |
1051 if (!dest_path) | |
1 | 1052 { |
9 | 1053 path_list_free(list); |
1054 return; | |
1055 } | |
1056 | |
1057 if (!list->next) | |
1058 { | |
1059 const gchar *source; | |
1060 gchar *dest; | |
1061 | |
1062 source = list->data; | |
1063 dest = concat_dir_and_file(dest_path, filename_from_path(source)); | |
1064 | |
1065 file_util_move_single(file_data_single_new(source, dest, TRUE)); | |
1066 g_free(dest); | |
1067 path_list_free(list); | |
1068 return; | |
1 | 1069 } |
9 | 1070 |
1071 file_util_move_multiple(file_data_multiple_new(list, dest_path, TRUE)); | |
1072 } | |
1073 | |
1074 /* | |
1075 *-------------------------------------------------------------------------- | |
1076 * Safe Delete | |
1077 *-------------------------------------------------------------------------- | |
1078 */ | |
1079 | |
1080 static gint file_util_safe_number(gint64 free_space) | |
1081 { | |
1082 gint n = 0; | |
1083 gint64 total = 0; | |
1084 GList *list; | |
1085 GList *work; | |
1086 gint sorted = FALSE; | |
1087 gint warned = FALSE; | |
1088 | |
1089 if (!filelist_read(safe_delete_path, &list, NULL)) return 0; | |
1090 | |
1091 work = list; | |
1092 while (work) | |
1 | 1093 { |
9 | 1094 FileData *fd; |
1095 gint v; | |
1096 | |
1097 fd = work->data; | |
1098 work = work->next; | |
1099 | |
1100 v = (gint)strtol(fd->name, NULL, 10); | |
1101 if (v >= n) n = v + 1; | |
1102 | |
1103 total += fd->size; | |
1 | 1104 } |
9 | 1105 |
1106 while (list && | |
1107 (free_space < 0 || total + free_space > (gint64)safe_delete_size * 1048576) ) | |
1108 { | |
1109 FileData *fd; | |
1110 | |
1111 if (!sorted) | |
1112 { | |
1113 list = filelist_sort(list, SORT_NAME, TRUE); | |
1114 sorted = TRUE; | |
1115 } | |
1116 | |
1117 fd = list->data; | |
1118 list = g_list_remove(list, fd); | |
1119 | |
1120 if (debug) printf("expunging from trash for space: %s\n", fd->name); | |
1121 if (!unlink_file(fd->path) && !warned) | |
1122 { | |
1123 file_util_warning_dialog(_("Delete failed"), | |
1124 _("Unable to remove old file from trash folder"), | |
1125 GTK_STOCK_DIALOG_WARNING, NULL); | |
1126 warned = TRUE; | |
1127 } | |
1128 total -= fd->size; | |
1129 file_data_free(fd); | |
1130 } | |
1131 | |
1132 filelist_free(list); | |
1133 | |
1134 return n; | |
1135 } | |
1136 | |
1137 void file_util_trash_clear(void) | |
1138 { | |
1139 file_util_safe_number(-1); | |
1140 } | |
1141 | |
1142 static gchar *file_util_safe_dest(const gchar *path) | |
1143 { | |
1144 gint n; | |
1145 | |
1146 n = file_util_safe_number(filesize(path)); | |
1147 return g_strdup_printf("%s/%06d_%s", safe_delete_path, n, filename_from_path(path)); | |
1148 } | |
1149 | |
1150 static void file_util_safe_del_toggle_cb(GtkWidget *button, gpointer data) | |
1151 { | |
1152 safe_delete_enable = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)); | |
1153 } | |
1154 | |
1155 static void file_util_safe_del_close_cb(GtkWidget *dialog, gpointer data) | |
1156 { | |
1157 GenericDialog **gd = data; | |
1158 | |
1159 *gd = NULL; | |
1 | 1160 } |
1161 | |
9 | 1162 static gint file_util_unlink(const gchar *path) |
1 | 1163 { |
9 | 1164 static GenericDialog *gd = NULL; |
1165 gchar *result = NULL; | |
1166 gint success = TRUE; | |
1167 | |
1168 if (!isfile(path)) return FALSE; | |
1169 | |
1170 if (!safe_delete_enable) | |
1171 { | |
1172 return unlink_file(path); | |
1173 } | |
1174 | |
1175 if (!isdir(safe_delete_path)) | |
1176 { | |
1177 if (debug) printf("creating trash: %s\n", safe_delete_path); | |
1178 if (!safe_delete_path || !mkdir_utf8(safe_delete_path, 0755)) | |
1179 { | |
1180 result = _("Could not create folder"); | |
1181 success = FALSE; | |
1182 } | |
1183 } | |
1184 | |
1185 if (success) | |
1186 { | |
1187 gchar *dest; | |
1188 | |
1189 dest = file_util_safe_dest(path); | |
1190 if (dest) | |
1191 { | |
1192 if (debug) printf("safe deleting %s to %s\n", path, dest); | |
1193 success = move_file(path, dest); | |
1194 } | |
1195 else | |
1196 { | |
1197 success = FALSE; | |
1198 } | |
1199 | |
1200 if (!success && !access_file(path, W_OK)) | |
1201 { | |
1202 result = _("Permission denied"); | |
1203 } | |
1204 g_free(dest); | |
1205 } | |
1206 | |
1207 if (result && !gd) | |
1208 { | |
1209 GtkWidget *button; | |
1210 gchar *buf; | |
1211 | |
1212 buf = g_strdup_printf(_("Unable to access or create the trash folder.\n\"%s\""), safe_delete_path); | |
1213 gd = file_util_warning_dialog(result, buf, GTK_STOCK_DIALOG_WARNING, NULL); | |
1214 g_free(buf); | |
1215 | |
1216 button = gtk_check_button_new_with_label(_("Turn off safe delete")); | |
1217 g_signal_connect(G_OBJECT(button), "toggled", | |
1218 G_CALLBACK(file_util_safe_del_toggle_cb), NULL); | |
1219 gtk_box_pack_start(GTK_BOX(gd->vbox), button, FALSE, FALSE, 0); | |
1220 gtk_widget_show(button); | |
1221 | |
1222 g_signal_connect(G_OBJECT(gd->dialog), "destroy", | |
1223 G_CALLBACK(file_util_safe_del_close_cb), &gd); | |
1224 } | |
1225 | |
1226 return success; | |
1 | 1227 } |
1228 | |
9 | 1229 static void box_append_safe_delete_status(GenericDialog *gd) |
1 | 1230 { |
9 | 1231 GtkWidget *label; |
1232 gchar *buf; | |
1233 | |
1234 buf = g_strdup_printf(_("Safe delete: %s"), (safe_delete_enable) ? _("on") : _("off")); | |
1235 label = pref_label_new(gd->vbox, buf); | |
1236 g_free(buf); | |
1237 | |
1238 gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); | |
1239 gtk_widget_set_sensitive(label, FALSE); | |
1 | 1240 } |
1241 | |
1242 /* | |
1243 *-------------------------------------------------------------------------- | |
1244 * Delete routines | |
1245 *-------------------------------------------------------------------------- | |
1246 */ | |
1247 | |
1248 /* | |
1249 * delete multiple files | |
1250 */ | |
1251 | |
9 | 1252 static void file_util_delete_multiple_ok_cb(GenericDialog *gd, gpointer data); |
1253 static void file_util_delete_multiple_cancel_cb(GenericDialog *gd, gpointer data); | |
1254 | |
1255 static void file_util_delete_multiple_ok_cb(GenericDialog *gd, gpointer data) | |
1 | 1256 { |
1257 GList *source_list = data; | |
1258 | |
9 | 1259 while (source_list) |
1 | 1260 { |
1261 gchar *path = source_list->data; | |
9 | 1262 |
1 | 1263 source_list = g_list_remove(source_list, path); |
9 | 1264 |
1265 if (!file_util_unlink(path)) | |
1 | 1266 { |
1267 if (source_list) | |
1268 { | |
9 | 1269 GenericDialog *d; |
1270 gchar *text; | |
1271 | |
1272 d = file_util_gen_dlg(_("Delete failed"), "GQview", "dlg_confirm", | |
1273 NULL, TRUE, | |
1274 file_util_delete_multiple_cancel_cb, source_list); | |
1275 | |
1 | 1276 text = g_strdup_printf(_("Unable to delete file:\n %s\n Continue multiple delete operation?"), path); |
9 | 1277 generic_dialog_add_message(d, GTK_STOCK_DIALOG_WARNING, NULL, text); |
1278 g_free(text); | |
1279 | |
1280 generic_dialog_add_button(d, GTK_STOCK_GO_FORWARD, _("Co_ntinue"), | |
1281 file_util_delete_multiple_ok_cb, TRUE); | |
1282 gtk_widget_show(d->dialog); | |
1 | 1283 } |
1284 else | |
1285 { | |
9 | 1286 gchar *text; |
1287 | |
1 | 1288 text = g_strdup_printf(_("Unable to delete file:\n%s"), path); |
9 | 1289 file_util_warning_dialog(_("Delete failed"), text, GTK_STOCK_DIALOG_ERROR, NULL); |
1290 g_free(text); | |
1 | 1291 } |
1292 g_free(path); | |
1293 return; | |
1294 } | |
1295 else | |
1296 { | |
9 | 1297 file_maint_removed(path, source_list); |
1 | 1298 } |
1299 g_free(path); | |
1300 } | |
1301 } | |
1302 | |
9 | 1303 static void file_util_delete_multiple_cancel_cb(GenericDialog *gd, gpointer data) |
1 | 1304 { |
1305 GList *source_list = data; | |
9 | 1306 |
1307 path_list_free(source_list); | |
1 | 1308 } |
1309 | |
9 | 1310 static void file_util_delete_multiple_review_skip(GenericDialog *gd, gint next) |
1311 { | |
1312 GtkWidget *button_back; | |
1313 GtkWidget *button_next; | |
1314 GtkWidget *button_label; | |
1315 GList *list; | |
1316 GList *list_point; | |
1317 const gchar *path; | |
1318 gchar *buf; | |
1319 | |
1320 list = gd->data; | |
1321 button_back = g_object_get_data(G_OBJECT(gd->dialog), "button_back"); | |
1322 button_next = g_object_get_data(G_OBJECT(gd->dialog), "button_next"); | |
1323 button_label = g_object_get_data(G_OBJECT(gd->dialog), "button_label"); | |
1324 list_point = g_object_get_data(G_OBJECT(gd->dialog), "list_point"); | |
1325 | |
1326 if (!list || !button_label) return; | |
1327 | |
1328 if (list_point) | |
1329 { | |
1330 if (next) | |
1331 { | |
1332 if (list_point->next) list_point = list_point->next; | |
1333 } | |
1334 else | |
1335 { | |
1336 if (list_point->prev) list_point = list_point->prev; | |
1337 } | |
1338 } | |
1339 else | |
1340 { | |
1341 list_point = list; | |
1342 } | |
1343 | |
1344 if (!list_point) return; | |
1345 | |
1346 path = list_point->data; | |
1347 buf = g_strdup_printf(_("File %d of %d"), | |
1348 g_list_index(list, (gpointer)path) + 1, | |
1349 g_list_length(list)); | |
1350 gtk_label_set_text(GTK_LABEL(button_label), buf); | |
1351 g_free(buf); | |
1352 | |
1353 gtk_widget_set_sensitive(button_back, (list_point->prev != NULL) ); | |
1354 gtk_widget_set_sensitive(button_next, (list_point->next != NULL) ); | |
1355 | |
1356 generic_dialog_image_set(gd, path); | |
1357 | |
1358 g_object_set_data(G_OBJECT(gd->dialog), "list_point", list_point); | |
1359 } | |
1360 | |
1361 static void file_util_delete_multiple_review_back(GtkWidget *button, gpointer data) | |
1362 { | |
1363 GenericDialog *gd = data; | |
1364 | |
1365 file_util_delete_multiple_review_skip(gd, FALSE); | |
1366 } | |
1367 | |
1368 static void file_util_delete_multiple_review_next(GtkWidget *button, gpointer data) | |
1369 { | |
1370 GenericDialog *gd = data; | |
1371 | |
1372 file_util_delete_multiple_review_skip(gd, TRUE); | |
1373 } | |
1374 | |
1375 static void file_util_delete_multiple_review_button_cb(ImageWindow *imd, gint button, guint32 time, | |
1376 gdouble x, gdouble y, guint state, gpointer data) | |
1377 { | |
1378 if (button == 1) | |
1379 { | |
1380 file_util_delete_multiple_review_next(NULL, data); | |
1381 } | |
1382 else if (button == 2 || button == 3) | |
1383 { | |
1384 file_util_delete_multiple_review_back(NULL, data); | |
1385 } | |
1386 } | |
1387 | |
1388 static void file_util_delete_multiple_review_scroll_cb(ImageWindow *imd, GdkScrollDirection direction, guint32 time, | |
1389 gdouble x, gdouble y, guint state, gpointer data) | |
1390 { | |
1391 if (direction == GDK_SCROLL_UP) | |
1392 { | |
1393 file_util_delete_multiple_review_back(NULL, data); | |
1394 } | |
1395 else if (direction == GDK_SCROLL_DOWN) | |
1396 { | |
1397 file_util_delete_multiple_review_next(NULL, data); | |
1398 } | |
1399 } | |
1400 | |
1401 static void file_util_delete_multiple(GList *source_list, GtkWidget *parent) | |
1 | 1402 { |
1403 if (!confirm_delete) | |
1404 { | |
1405 file_util_delete_multiple_ok_cb(NULL, source_list); | |
1406 } | |
1407 else | |
1408 { | |
9 | 1409 GenericDialog *gd; |
1410 GtkWidget *hbox; | |
1411 GtkWidget *button; | |
1412 GtkWidget *label; | |
1413 ImageWindow *imd; | |
1414 gchar *buf; | |
1415 | |
1416 gd = file_util_gen_dlg(_("Delete files - GQview"), | |
1417 "GQview", "dlg_confirm", parent, TRUE, | |
1418 file_util_delete_multiple_cancel_cb, source_list); | |
1419 | |
1420 generic_dialog_add_message(gd, NULL, _("Delete multiple files"), NULL); | |
1421 | |
1422 generic_dialog_add_image(gd, NULL, NULL, NULL, NULL, TRUE); | |
1423 imd = g_object_get_data(G_OBJECT(gd->dialog), "img_image"); | |
1424 image_set_button_func(imd, file_util_delete_multiple_review_button_cb, gd); | |
1425 image_set_scroll_func(imd, file_util_delete_multiple_review_scroll_cb, gd); | |
1426 | |
1427 hbox = pref_box_new(gd->vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP); | |
1428 | |
1429 button = pref_button_new(hbox, GTK_STOCK_GO_BACK, NULL, TRUE, | |
1430 G_CALLBACK(file_util_delete_multiple_review_back), gd); | |
1431 gtk_widget_set_sensitive(button, FALSE); | |
1432 g_object_set_data(G_OBJECT(gd->dialog), "button_back", button); | |
1433 | |
1434 button = pref_button_new(hbox, GTK_STOCK_GO_FORWARD, NULL, TRUE, | |
1435 G_CALLBACK(file_util_delete_multiple_review_next), gd); | |
1436 g_object_set_data(G_OBJECT(gd->dialog), "button_next", button); | |
1437 | |
1438 buf = g_strdup_printf(_("Review %d files"), g_list_length(source_list) ); | |
1439 label = pref_label_new(hbox, buf); | |
1440 g_free(buf); | |
1441 g_object_set_data(G_OBJECT(gd->dialog), "button_label", label); | |
1442 | |
1443 box_append_safe_delete_status(gd); | |
1444 | |
1445 generic_dialog_add_button(gd, GTK_STOCK_DELETE, NULL, file_util_delete_multiple_ok_cb, TRUE); | |
1446 | |
1447 gtk_widget_show(gd->dialog); | |
1 | 1448 } |
1449 } | |
1450 | |
1451 /* | |
1452 * delete single file | |
1453 */ | |
1454 | |
9 | 1455 static void file_util_delete_ok_cb(GenericDialog *gd, gpointer data) |
1 | 1456 { |
1457 gchar *path = data; | |
1458 | |
9 | 1459 if (!file_util_unlink(path)) |
1 | 1460 { |
1461 gchar *text = g_strdup_printf(_("Unable to delete file:\n%s"), path); | |
9 | 1462 file_util_warning_dialog(_("File deletion failed"), text, GTK_STOCK_DIALOG_ERROR, NULL); |
1 | 1463 g_free(text); |
1464 } | |
1465 else | |
1466 { | |
9 | 1467 file_maint_removed(path, NULL); |
1 | 1468 } |
1469 | |
1470 g_free(path); | |
1471 } | |
1472 | |
9 | 1473 static void file_util_delete_cancel_cb(GenericDialog *gd, gpointer data) |
1 | 1474 { |
1475 gchar *path = data; | |
9 | 1476 |
1 | 1477 g_free(path); |
1478 } | |
1479 | |
9 | 1480 static void file_util_delete_single(const gchar *path, GtkWidget *parent) |
1 | 1481 { |
1482 gchar *buf = g_strdup(path); | |
1483 | |
1484 if (!confirm_delete) | |
1485 { | |
1486 file_util_delete_ok_cb(NULL, buf); | |
1487 } | |
1488 else | |
1489 { | |
9 | 1490 GenericDialog *gd; |
1491 GtkWidget *table; | |
1492 gchar *base; | |
1493 | |
1494 gd = file_util_gen_dlg(_("Delete file - GQview"), "GQview", "dlg_confirm", | |
1495 parent, TRUE, | |
1496 file_util_delete_cancel_cb, buf); | |
1497 | |
1498 generic_dialog_add_message(gd, NULL, _("Delete file?"), NULL); | |
1499 | |
1500 table = pref_table_new(gd->vbox, 2, 2, FALSE, FALSE); | |
1501 | |
1502 pref_table_label(table, 0, 0, _("File name:"), 1.0); | |
1503 pref_table_label(table, 1, 0, filename_from_path(path), 0.0); | |
1504 | |
1505 pref_table_label(table, 0, 1, _("Location:"), 1.0); | |
1506 | |
1507 base = remove_level_from_path(path); | |
1508 pref_table_label(table, 1, 1, base, 0.0); | |
1509 g_free(base); | |
1510 | |
1511 generic_dialog_add_image(gd, path, NULL, NULL, NULL, FALSE); | |
1512 | |
1513 box_append_safe_delete_status(gd); | |
1514 | |
1515 generic_dialog_add_button(gd, GTK_STOCK_DELETE, NULL, file_util_delete_ok_cb, TRUE); | |
1516 | |
1517 gtk_widget_show(gd->dialog); | |
1 | 1518 } |
1519 } | |
1520 | |
9 | 1521 void file_util_delete(const gchar *source_path, GList *source_list, GtkWidget *parent) |
1 | 1522 { |
1523 if (!source_path && !source_list) return; | |
1524 | |
1525 if (source_path) | |
1526 { | |
9 | 1527 file_util_delete_single(source_path, parent); |
1 | 1528 } |
1529 else if (!source_list->next) | |
1530 { | |
9 | 1531 file_util_delete_single(source_list->data, parent); |
1532 path_list_free(source_list); | |
1 | 1533 } |
1534 else | |
1535 { | |
9 | 1536 file_util_delete_multiple(source_list, parent); |
1 | 1537 } |
1538 } | |
1539 | |
1540 /* | |
1541 *-------------------------------------------------------------------------- | |
1542 * Rename routines | |
1543 *-------------------------------------------------------------------------- | |
1544 */ | |
1545 | |
1546 /* | |
1547 * rename multiple files | |
1548 */ | |
1549 | |
9 | 1550 enum { |
1551 RENAME_COLUMN_PATH = 0, | |
1552 RENAME_COLUMN_NAME, | |
1553 RENAME_COLUMN_PREVIEW, | |
1554 RENAME_COLUMN_COUNT | |
1555 }; | |
1556 | |
1557 typedef struct _RenameDataMult RenameDataMult; | |
1558 struct _RenameDataMult | |
1 | 1559 { |
9 | 1560 FileDialog *fd; |
1561 | |
1562 gint rename_auto; | |
1563 | |
1564 GtkWidget *listview; | |
1565 GtkWidget *button_auto; | |
1566 | |
1567 GtkWidget *rename_box; | |
1568 GtkWidget *rename_label; | |
1569 GtkWidget *rename_entry; | |
1570 | |
1571 GtkWidget *auto_box; | |
1572 GtkWidget *auto_entry_front; | |
1573 GtkWidget *auto_spin_start; | |
1574 GtkWidget *auto_spin_pad; | |
1575 GtkWidget *auto_entry_end; | |
1576 | |
1577 ImageWindow *imd; | |
1578 | |
1579 gint update_idle_id; | |
1580 }; | |
1581 | |
1582 static void file_util_rename_multiple(RenameDataMult *rd); | |
1583 | |
1584 static void file_util_rename_multiple_ok_cb(GenericDialog *gd, gpointer data) | |
1585 { | |
1586 RenameDataMult *rd = data; | |
1587 GtkWidget *dialog; | |
1588 | |
1589 dialog = GENERIC_DIALOG(rd->fd)->dialog; | |
1590 if (!GTK_WIDGET_VISIBLE(dialog)) gtk_widget_show(dialog); | |
1591 | |
1592 rd->fd->type = TRUE; | |
1593 file_util_rename_multiple(rd); | |
1 | 1594 } |
1595 | |
9 | 1596 static void file_util_rename_multiple_cancel_cb(GenericDialog *gd, gpointer data) |
1597 { | |
1598 RenameDataMult *rd = data; | |
1599 GtkWidget *dialog; | |
1600 | |
1601 dialog = GENERIC_DIALOG(rd->fd)->dialog; | |
1602 if (!GTK_WIDGET_VISIBLE(dialog)) gtk_widget_show(dialog); | |
1603 } | |
1604 | |
1605 static gint file_util_rename_multiple_find_row(RenameDataMult *rd, const gchar *path, GtkTreeIter *iter) | |
1 | 1606 { |
9 | 1607 GtkTreeModel *store; |
1608 gint valid; | |
1609 gint row = 0; | |
1610 | |
1611 store = gtk_tree_view_get_model(GTK_TREE_VIEW(rd->listview)); | |
1612 valid = gtk_tree_model_get_iter_first(store, iter); | |
1613 while (valid) | |
1614 { | |
1615 gchar *path_n; | |
1616 gint ret; | |
1617 | |
1618 gtk_tree_model_get(GTK_TREE_MODEL(store), iter, RENAME_COLUMN_PATH, &path_n, -1); | |
1619 ret = (strcmp(path_n, path) == 0); | |
1620 g_free(path_n); | |
1621 if (ret) return row; | |
1622 | |
1623 valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), iter); | |
1624 row++; | |
1625 } | |
1626 | |
1627 return -1; | |
1 | 1628 } |
1629 | |
9 | 1630 static void file_util_rename_multiple(RenameDataMult *rd) |
1 | 1631 { |
9 | 1632 FileDialog *fd; |
1633 | |
1634 fd = rd->fd; | |
1635 | |
1 | 1636 if (isfile(fd->dest_path) && !fd->type) |
1637 { | |
9 | 1638 GenericDialog *gd; |
1639 | |
1640 gd = file_util_gen_dlg(_("Overwrite file"), "GQview", "dlg_confirm", | |
1641 NULL, TRUE, | |
1642 file_util_rename_multiple_cancel_cb, rd); | |
1643 | |
1644 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, | |
1645 _("Overwrite file?"), | |
1646 _("Replace existing file by renaming new file.")); | |
1647 pref_spacer(gd->vbox, 0); | |
1648 | |
1649 generic_dialog_add_button(gd, GTK_STOCK_OK, _("_Overwrite"), file_util_rename_multiple_ok_cb, TRUE); | |
1650 generic_dialog_add_image(gd, fd->dest_path, _("Existing file"), fd->source_path, _("New file"), TRUE); | |
1651 | |
1652 gtk_widget_hide(GENERIC_DIALOG(fd)->dialog); | |
1653 | |
1654 gtk_widget_show(gd->dialog); | |
1 | 1655 return; |
1656 } | |
1657 else | |
1658 { | |
9 | 1659 if (!rename_file(fd->source_path, fd->dest_path)) |
1 | 1660 { |
9 | 1661 gchar *text = g_strdup_printf(_("Unable to rename file:\n%s\n to:\n%s"), |
1662 filename_from_path(fd->source_path), | |
1663 filename_from_path(fd->dest_path)); | |
1664 file_util_warning_dialog(_("Error renaming file"), text, GTK_STOCK_DIALOG_ERROR, NULL); | |
1 | 1665 g_free(text); |
1666 } | |
1667 else | |
1668 { | |
9 | 1669 GtkTreeModel *store; |
1670 GtkTreeIter iter; | |
1671 GtkTreeIter next; | |
1 | 1672 gint row; |
9 | 1673 |
1674 file_maint_renamed(fd->source_path, fd->dest_path); | |
1675 | |
1676 store = gtk_tree_view_get_model(GTK_TREE_VIEW(rd->listview)); | |
1677 row = file_util_rename_multiple_find_row(rd, rd->fd->source_path, &iter); | |
1678 | |
1679 if (row >= 0 && | |
1680 (gtk_tree_model_iter_nth_child(store, &next, NULL, row + 1) || | |
1681 (row > 0 && gtk_tree_model_iter_nth_child(store, &next, NULL, row - 1)) ) ) | |
1 | 1682 { |
9 | 1683 GtkTreeSelection *selection; |
1684 | |
1685 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(rd->listview)); | |
1686 gtk_tree_selection_select_iter(selection, &next); | |
1687 gtk_list_store_remove(GTK_LIST_STORE(store), &iter); | |
1 | 1688 } |
1689 else | |
1690 { | |
9 | 1691 if (debug) printf("closed by #%d\n", row); |
1692 | |
1693 file_dialog_close(rd->fd); | |
1 | 1694 } |
1695 } | |
1696 } | |
1697 } | |
1698 | |
9 | 1699 static void file_util_rename_multiple_auto(RenameDataMult *rd) |
1 | 1700 { |
9 | 1701 const gchar *front; |
1702 const gchar *end; | |
1703 gint start_n; | |
1704 gint padding; | |
1705 gint n; | |
1706 GtkTreeModel *store; | |
1707 GtkTreeIter iter; | |
1708 gint valid; | |
1709 gint success; | |
1710 | |
1711 history_combo_append_history(rd->auto_entry_front, NULL); | |
1712 history_combo_append_history(rd->auto_entry_end, NULL); | |
1713 | |
1714 front = gtk_entry_get_text(GTK_ENTRY(rd->auto_entry_front)); | |
1715 end = gtk_entry_get_text(GTK_ENTRY(rd->auto_entry_end)); | |
1716 start_n = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(rd->auto_spin_start)); | |
1717 padding = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(rd->auto_spin_pad)); | |
1718 | |
1719 store = gtk_tree_view_get_model(GTK_TREE_VIEW(rd->listview)); | |
1720 | |
1721 /* first check for name conflicts */ | |
1722 success = TRUE; | |
1723 n = start_n; | |
1724 valid = gtk_tree_model_get_iter_first(store, &iter); | |
1725 while (valid && success) | |
1726 { | |
1727 gchar *dest; | |
1728 gchar *base; | |
1729 gchar *path; | |
1730 | |
1731 gtk_tree_model_get(store, &iter, RENAME_COLUMN_PATH, &path, -1); | |
1732 | |
1733 base = remove_level_from_path(path); | |
1734 dest = g_strdup_printf("%s/%s%0*d%s", base, front, padding, n, end); | |
1735 if (isname(dest)) success = FALSE; | |
1736 g_free(dest); | |
1737 g_free(base); | |
1738 g_free(path); | |
1739 | |
1740 n++; | |
1741 valid = gtk_tree_model_iter_next(store, &iter); | |
1742 } | |
1743 | |
1744 if (!success) | |
1745 { | |
1746 file_util_warning_dialog(_("Auto rename"), | |
1747 _("Can not auto rename with the selected\nnumber set, one or more files exist that\nmatch the resulting name list.\n"), | |
1748 GTK_STOCK_DIALOG_WARNING, NULL); | |
1749 return; | |
1750 } | |
1751 | |
1752 /* select the first iter, so that on fail the correct info is given to user */ | |
1753 if (gtk_tree_model_get_iter_first(store, &iter)) | |
1754 { | |
1755 GtkTreeSelection *selection; | |
1756 | |
1757 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(rd->listview)); | |
1758 gtk_tree_selection_select_iter(selection, &iter); | |
1759 } | |
1760 | |
1761 /* now do it for real */ | |
1762 success = TRUE; | |
1763 n = start_n; | |
1764 while (success && gtk_tree_model_get_iter_first(store, &iter)) | |
1765 { | |
1766 gchar *dest; | |
1767 gchar *base; | |
1768 gchar *path; | |
1769 | |
1770 gtk_tree_model_get(store, &iter, RENAME_COLUMN_PATH, &path, -1); | |
1771 | |
1772 base = remove_level_from_path(path); | |
1773 dest = g_strdup_printf("%s/%s%0*d%s", base, front, padding, n, end); | |
1774 if (!rename_file(path, dest)) | |
1775 { | |
1776 success = FALSE; | |
1777 } | |
1778 else | |
1779 { | |
1780 file_maint_renamed(path, dest); | |
1781 } | |
1782 | |
1783 g_free(dest); | |
1784 g_free(base); | |
1785 g_free(path); | |
1786 | |
1787 if (success) | |
1788 { | |
1789 gtk_list_store_remove(GTK_LIST_STORE(store), &iter); | |
1790 if (gtk_tree_model_get_iter_first(store, &iter)) | |
1791 { | |
1792 GtkTreeSelection *selection; | |
1793 | |
1794 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(rd->listview)); | |
1795 gtk_tree_selection_select_iter(selection, &iter); | |
1796 } | |
1797 } | |
1798 | |
1799 n++; | |
1800 } | |
1801 | |
1802 if (!success) | |
1803 { | |
1804 gchar *buf; | |
1805 | |
1806 n--; | |
15
3263965d5f9e
##### Note: GQview CVS on sourceforge is not always up to date, please use #####
gqview
parents:
9
diff
changeset
|
1807 gtk_spin_button_set_value(GTK_SPIN_BUTTON(rd->auto_spin_start), (gdouble)n); |
9 | 1808 |
1809 buf = g_strdup_printf(_("Failed to rename\n%s\nThe number was %d."), filename_from_path(rd->fd->source_path), n); | |
1810 file_util_warning_dialog(_("Auto rename"), buf, GTK_STOCK_DIALOG_ERROR, NULL); | |
1811 g_free(buf); | |
1812 | |
1813 return; | |
1814 } | |
1815 | |
1816 file_dialog_close(rd->fd); | |
1817 } | |
1818 | |
1819 static void file_util_rename_multiple_cb(FileDialog *fd, gpointer data) | |
1820 { | |
1821 RenameDataMult *rd = data; | |
1 | 1822 gchar *base; |
9 | 1823 const gchar *name; |
1824 | |
1825 if (rd->rename_auto) | |
1826 { | |
1827 file_util_rename_multiple_auto(rd); | |
1828 return; | |
1829 } | |
1830 | |
1831 name = gtk_entry_get_text(GTK_ENTRY(rd->rename_entry)); | |
1 | 1832 base = remove_level_from_path(fd->source_path); |
9 | 1833 |
1 | 1834 g_free(fd->dest_path); |
9 | 1835 fd->dest_path = concat_dir_and_file(base, name); |
1 | 1836 g_free(base); |
1837 | |
1838 if (strlen(name) == 0 || strcmp(fd->source_path, fd->dest_path) == 0) | |
1839 { | |
1840 return; | |
1841 } | |
1842 | |
1843 fd->type = FALSE; | |
9 | 1844 file_util_rename_multiple(rd); |
1845 } | |
1846 | |
1847 static void file_util_rename_multiple_close_cb(FileDialog *fd, gpointer data) | |
1848 { | |
1849 RenameDataMult *rd = data; | |
1850 | |
1851 file_dialog_close(rd->fd); | |
1 | 1852 } |
1853 | |
9 | 1854 static gboolean file_util_rename_multiple_select_cb(GtkTreeSelection *selection, GtkTreeModel *store, GtkTreePath *tpath, |
1855 gboolean path_currently_selected, gpointer data) | |
1856 { | |
1857 RenameDataMult *rd = data; | |
1858 GtkTreeIter iter; | |
1859 const gchar *name; | |
1860 gchar *path = NULL; | |
1861 | |
1862 if (path_currently_selected || | |
1863 !gtk_tree_model_get_iter(store, &iter, tpath)) return TRUE; | |
1864 gtk_tree_model_get(store, &iter, RENAME_COLUMN_PATH, &path, -1); | |
1865 | |
1866 g_free(rd->fd->source_path); | |
1867 rd->fd->source_path = path; | |
1868 | |
1869 name = filename_from_path(rd->fd->source_path); | |
1870 gtk_label_set_text(GTK_LABEL(rd->rename_label), name); | |
1871 gtk_entry_set_text(GTK_ENTRY(rd->rename_entry), name); | |
1872 | |
1873 image_change_path(rd->imd, rd->fd->source_path, 0.0); | |
1874 | |
1875 if (GTK_WIDGET_VISIBLE(rd->rename_box)) | |
1876 { | |
1877 gtk_widget_grab_focus(rd->rename_entry); | |
1878 } | |
1879 | |
1880 return TRUE; | |
1881 } | |
1882 | |
1883 static void file_util_rename_multiple_preview_update(RenameDataMult *rd) | |
1 | 1884 { |
9 | 1885 GtkTreeModel *store; |
1886 GtkTreeIter iter; | |
1887 const gchar *front; | |
1888 const gchar *end; | |
1889 gint valid; | |
1890 gint start_n; | |
1891 gint padding; | |
1892 gint n; | |
1893 | |
1894 front = gtk_entry_get_text(GTK_ENTRY(rd->auto_entry_front)); | |
1895 end = gtk_entry_get_text(GTK_ENTRY(rd->auto_entry_end)); | |
1896 start_n = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(rd->auto_spin_start)); | |
1897 padding = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(rd->auto_spin_pad)); | |
1898 | |
1899 store = gtk_tree_view_get_model(GTK_TREE_VIEW(rd->listview)); | |
1900 n = start_n; | |
1901 valid = gtk_tree_model_get_iter_first(store, &iter); | |
1902 while (valid) | |
1903 { | |
1904 gchar *dest; | |
1905 | |
1906 dest = g_strdup_printf("%s%0*d%s", front, padding, n, end); | |
1907 gtk_list_store_set(GTK_LIST_STORE(store), &iter, RENAME_COLUMN_PREVIEW, dest, -1); | |
1908 g_free(dest); | |
1909 | |
1910 n++; | |
1911 valid = gtk_tree_model_iter_next(store, &iter); | |
1912 } | |
1913 | |
1 | 1914 } |
1915 | |
9 | 1916 static gboolean file_util_rename_multiple_idle_cb(gpointer data) |
1917 { | |
1918 RenameDataMult *rd = data; | |
1919 | |
1920 file_util_rename_multiple_preview_update(rd); | |
1921 | |
1922 rd->update_idle_id = -1; | |
1923 return FALSE; | |
1924 } | |
1925 | |
1926 static void file_util_rename_multiple_preview_order_cb(GtkTreeModel *treemodel, GtkTreePath *tpath, | |
1927 GtkTreeIter *iter, gpointer data) | |
1928 { | |
1929 RenameDataMult *rd = data; | |
1930 | |
1931 if (rd->rename_auto && rd->update_idle_id == -1) | |
1932 { | |
1933 rd->update_idle_id = g_idle_add(file_util_rename_multiple_idle_cb, rd); | |
1934 } | |
1935 } | |
1936 | |
1937 static void file_util_rename_multiple_preview_entry_cb(GtkWidget *entry, gpointer data) | |
1938 { | |
1939 RenameDataMult *rd = data; | |
1940 file_util_rename_multiple_preview_update(rd); | |
1941 } | |
1942 | |
1943 static void file_util_rename_multiple_preview_adj_cb(GtkWidget *spin, gpointer data) | |
1944 { | |
1945 RenameDataMult *rd = data; | |
1946 file_util_rename_multiple_preview_update(rd); | |
1947 } | |
1948 | |
1949 static void file_util_rename_mulitple_auto_toggle(GtkWidget *widget, gpointer data) | |
1 | 1950 { |
9 | 1951 RenameDataMult *rd = data; |
1952 GtkTreeViewColumn *column; | |
1953 | |
1954 rd->rename_auto = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rd->button_auto)); | |
1955 | |
1956 if (rd->rename_auto) | |
1957 { | |
1958 if (GTK_WIDGET_VISIBLE(rd->rename_box)) gtk_widget_hide(rd->rename_box); | |
1959 if (!GTK_WIDGET_VISIBLE(rd->auto_box)) gtk_widget_show(rd->auto_box); | |
1960 file_util_rename_multiple_preview_update(rd); | |
1961 } | |
1962 else | |
1963 { | |
1964 if (GTK_WIDGET_VISIBLE(rd->auto_box)) gtk_widget_hide(rd->auto_box); | |
1965 if (!GTK_WIDGET_VISIBLE(rd->rename_box)) gtk_widget_show(rd->rename_box); | |
1966 } | |
1967 | |
1968 column = gtk_tree_view_get_column(GTK_TREE_VIEW(rd->listview), RENAME_COLUMN_PREVIEW - 1); | |
1969 gtk_tree_view_column_set_visible(column, rd->rename_auto); | |
1970 } | |
1971 | |
1972 static GtkWidget *furm_simple_vlabel(GtkWidget *box, const gchar *text, gint expand) | |
1973 { | |
1974 GtkWidget *vbox; | |
1975 GtkWidget *label; | |
1976 | |
1977 vbox = gtk_vbox_new(FALSE, 0); | |
1978 gtk_box_pack_start(GTK_BOX(box), vbox, expand, expand, 0); | |
1979 gtk_widget_show(vbox); | |
1980 | |
1981 label = gtk_label_new(text); | |
1982 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
1983 gtk_widget_show(label); | |
1984 | |
1985 return vbox; | |
1986 } | |
1987 | |
1988 static GtkTreeViewColumn *file_util_rename_multiple_add_column(RenameDataMult *rd, const gchar *text, gint n) | |
1989 { | |
1990 GtkTreeViewColumn *column; | |
1991 GtkCellRenderer *renderer; | |
1992 | |
1993 column = gtk_tree_view_column_new(); | |
1994 gtk_tree_view_column_set_title(column, text); | |
1995 gtk_tree_view_column_set_min_width(column, 4); | |
1996 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_GROW_ONLY); | |
1997 renderer = gtk_cell_renderer_text_new(); | |
1998 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
1999 gtk_tree_view_column_add_attribute(column, renderer, "text", n); | |
2000 gtk_tree_view_append_column(GTK_TREE_VIEW(rd->listview), column); | |
2001 | |
2002 return column; | |
2003 } | |
2004 | |
2005 static void file_util_rename_multiple_destroy_cb(GtkWidget *widget, gpointer data) | |
2006 { | |
2007 RenameDataMult *rd = data; | |
2008 | |
2009 if (rd->update_idle_id != -1) g_source_remove(rd->update_idle_id); | |
2010 | |
2011 g_free(rd); | |
2012 } | |
2013 | |
2014 static void file_util_rename_multiple_do(GList *source_list, GtkWidget *parent) | |
2015 { | |
2016 RenameDataMult *rd; | |
2017 GtkWidget *pane; | |
1 | 2018 GtkWidget *scrolled; |
9 | 2019 GtkListStore *store; |
2020 GtkTreeSelection *selection; | |
2021 GtkTreeViewColumn *column; | |
2022 GtkWidget *hbox; | |
2023 GtkWidget *vbox; | |
2024 GtkWidget *box2; | |
2025 GtkWidget *table; | |
2026 GtkWidget *combo; | |
1 | 2027 GList *work; |
2028 | |
9 | 2029 rd = g_new0(RenameDataMult, 1); |
2030 | |
2031 rd->fd = file_util_file_dlg(_("Rename - GQview"), | |
2032 "GQview", "dlg_rename", parent, | |
2033 file_util_rename_multiple_close_cb, rd); | |
2034 generic_dialog_add_message(GENERIC_DIALOG(rd->fd), NULL, _("Rename multiple files"), NULL); | |
2035 file_dialog_add_button(rd->fd, GTK_STOCK_OK, _("_Rename"), file_util_rename_multiple_cb, TRUE); | |
2036 | |
2037 rd->fd->source_path = g_strdup(source_list->data); | |
2038 rd->fd->dest_path = NULL; | |
2039 | |
2040 rd->update_idle_id = -1; | |
2041 | |
2042 vbox = GENERIC_DIALOG(rd->fd)->vbox; | |
2043 | |
2044 pane = gtk_hpaned_new(); | |
2045 gtk_box_pack_start(GTK_BOX(vbox), pane, TRUE, TRUE, 0); | |
2046 gtk_widget_show(pane); | |
2047 | |
1 | 2048 scrolled = gtk_scrolled_window_new(NULL, NULL); |
9 | 2049 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN); |
2050 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled), | |
2051 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); | |
2052 gtk_paned_pack1(GTK_PANED(pane), scrolled, TRUE, TRUE); | |
1 | 2053 gtk_widget_show(scrolled); |
2054 | |
9 | 2055 store = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); |
2056 rd->listview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); | |
2057 g_object_unref(store); | |
2058 | |
2059 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(rd->listview), TRUE); | |
2060 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(rd->listview), FALSE); | |
2061 | |
2062 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(rd->listview)); | |
2063 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_SINGLE); | |
2064 gtk_tree_selection_set_select_function(selection, file_util_rename_multiple_select_cb, rd, NULL); | |
2065 | |
2066 file_util_rename_multiple_add_column(rd, _("Original Name"), RENAME_COLUMN_NAME); | |
2067 column = file_util_rename_multiple_add_column(rd, _("Preview"), RENAME_COLUMN_PREVIEW); | |
2068 gtk_tree_view_column_set_visible(column, FALSE); | |
2069 | |
2070 gtk_tree_view_set_reorderable(GTK_TREE_VIEW(rd->listview), TRUE); | |
2071 g_signal_connect(G_OBJECT(store), "row_changed", | |
2072 G_CALLBACK(file_util_rename_multiple_preview_order_cb), rd); | |
2073 gtk_widget_set_size_request(rd->listview, 250, 150); | |
2074 | |
2075 gtk_container_add(GTK_CONTAINER(scrolled), rd->listview); | |
2076 gtk_widget_show(rd->listview); | |
1 | 2077 |
2078 work = source_list; | |
9 | 2079 while (work) |
1 | 2080 { |
9 | 2081 gchar *path = work->data; |
2082 GtkTreeIter iter; | |
2083 | |
2084 gtk_list_store_append(store, &iter); | |
2085 gtk_list_store_set(store, &iter, RENAME_COLUMN_PATH, path, RENAME_COLUMN_NAME, filename_from_path(path), -1); | |
2086 | |
1 | 2087 work = work->next; |
2088 } | |
2089 | |
9 | 2090 path_list_free(source_list); |
2091 | |
2092 rd->imd = image_new(TRUE); | |
2093 gtk_widget_set_size_request(rd->imd->widget, DIALOG_DEF_IMAGE_DIM_X, DIALOG_DEF_IMAGE_DIM_Y); | |
2094 gtk_paned_pack2(GTK_PANED(pane), rd->imd->widget, FALSE, TRUE); | |
2095 gtk_widget_show(rd->imd->widget); | |
2096 | |
2097 hbox = gtk_hbox_new(FALSE, 0); | |
2098 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
2099 gtk_widget_show(hbox); | |
2100 | |
2101 rd->button_auto = gtk_check_button_new_with_label(_("Auto rename")); | |
2102 g_signal_connect(G_OBJECT(rd->button_auto), "clicked", | |
2103 G_CALLBACK(file_util_rename_mulitple_auto_toggle), rd); | |
2104 gtk_box_pack_end(GTK_BOX(hbox), rd->button_auto, FALSE, FALSE, 0); | |
2105 gtk_widget_show(rd->button_auto); | |
2106 | |
2107 rd->rename_box = pref_box_new(vbox, FALSE, GTK_ORIENTATION_VERTICAL, 0); | |
2108 table = pref_table_new(rd->rename_box, 2, 2, FALSE, FALSE); | |
2109 | |
2110 pref_table_label(table, 0, 0, _("Original name:"), 1.0); | |
2111 rd->rename_label = pref_table_label(table, 1, 0, filename_from_path(rd->fd->source_path), 0.0); | |
2112 | |
2113 pref_table_label(table, 0, 1, _("New name:"), 1.0); | |
2114 | |
2115 rd->rename_entry = gtk_entry_new(); | |
2116 gtk_entry_set_text(GTK_ENTRY(rd->rename_entry), filename_from_path(rd->fd->source_path)); | |
2117 gtk_table_attach(GTK_TABLE(table), rd->rename_entry, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, FALSE, 0, 0); | |
2118 generic_dialog_attach_default(GENERIC_DIALOG(rd->fd), rd->rename_entry); | |
2119 gtk_widget_grab_focus(rd->rename_entry); | |
2120 gtk_widget_show(rd->rename_entry); | |
2121 | |
2122 rd->auto_box = gtk_vbox_new(FALSE, PREF_PAD_GAP); | |
2123 gtk_box_pack_start(GTK_BOX(vbox), rd->auto_box, FALSE, FALSE, 0); | |
2124 /* do not show it here */ | |
2125 | |
2126 hbox = pref_box_new(rd->auto_box, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_GAP); | |
2127 | |
2128 box2 = furm_simple_vlabel(hbox, _("Begin text"), TRUE); | |
2129 | |
2130 combo = history_combo_new(&rd->auto_entry_front, "", "numerical_rename_prefix", -1); | |
2131 g_signal_connect(G_OBJECT(rd->auto_entry_front), "changed", | |
2132 G_CALLBACK(file_util_rename_multiple_preview_entry_cb), rd); | |
2133 gtk_box_pack_start(GTK_BOX(box2), combo, TRUE, TRUE, 0); | |
2134 gtk_widget_show(combo); | |
2135 | |
2136 box2 = furm_simple_vlabel(hbox, _("Start #"), FALSE); | |
2137 | |
2138 rd->auto_spin_start = pref_spin_new(box2, NULL, NULL, | |
2139 0.0, 1000000.0, 1.0, 0, 0.0, | |
2140 G_CALLBACK(file_util_rename_multiple_preview_adj_cb), rd); | |
2141 | |
2142 box2 = furm_simple_vlabel(hbox, _("End text"), TRUE); | |
2143 | |
2144 combo = history_combo_new(&rd->auto_entry_end, "", "numerical_rename_suffix", -1); | |
2145 g_signal_connect(G_OBJECT(rd->auto_entry_end), "changed", | |
2146 G_CALLBACK(file_util_rename_multiple_preview_entry_cb), rd); | |
2147 gtk_box_pack_start(GTK_BOX(box2), combo, TRUE, TRUE, 0); | |
2148 gtk_widget_show(combo); | |
2149 | |
2150 rd->auto_spin_pad = pref_spin_new(rd->auto_box, _("Padding:"), NULL, | |
2151 1.0, 8.0, 1.0, 0, 1.0, | |
2152 G_CALLBACK(file_util_rename_multiple_preview_adj_cb), rd); | |
2153 | |
2154 image_change_path(rd->imd, rd->fd->source_path, 0.0); | |
2155 | |
2156 g_signal_connect(G_OBJECT(GENERIC_DIALOG(rd->fd)->dialog), "destroy", | |
2157 G_CALLBACK(file_util_rename_multiple_destroy_cb), rd); | |
2158 | |
2159 gtk_widget_show(GENERIC_DIALOG(rd->fd)->dialog); | |
1 | 2160 } |
2161 | |
2162 /* | |
2163 * rename single file | |
2164 */ | |
2165 | |
9 | 2166 static void file_util_rename_single(FileDataSingle *fds); |
2167 | |
2168 static void file_util_rename_single_ok_cb(GenericDialog *gd, gpointer data) | |
1 | 2169 { |
2170 FileDataSingle *fds = data; | |
2171 fds->confirmed = TRUE; | |
2172 file_util_rename_single(fds); | |
2173 } | |
2174 | |
9 | 2175 static void file_util_rename_single_cancel_cb(GenericDialog *gd, gpointer data) |
1 | 2176 { |
2177 FileDataSingle *fds = data; | |
2178 file_data_single_free(fds); | |
2179 } | |
2180 | |
2181 static void file_util_rename_single(FileDataSingle *fds) | |
2182 { | |
2183 if (isfile(fds->dest) && !fds->confirmed) | |
2184 { | |
9 | 2185 GenericDialog *gd; |
2186 | |
2187 gd = file_util_gen_dlg(_("Overwrite file"), "GQview", "dlg_confirm", | |
2188 NULL, TRUE, | |
2189 file_util_rename_single_cancel_cb, fds); | |
2190 | |
2191 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, | |
2192 _("Overwrite file?"), | |
2193 _("Replace existing file by renaming new file.")); | |
2194 pref_spacer(gd->vbox, 0); | |
2195 | |
2196 generic_dialog_add_button(gd, GTK_STOCK_OK, _("_Overwrite"), file_util_rename_single_ok_cb, TRUE); | |
2197 generic_dialog_add_image(gd, fds->dest, _("Existing file"), fds->source, _("New file"), TRUE); | |
2198 | |
2199 gtk_widget_show(gd->dialog); | |
2200 | |
1 | 2201 return; |
2202 } | |
2203 else | |
2204 { | |
9 | 2205 if (!rename_file(fds->source, fds->dest)) |
1 | 2206 { |
2207 gchar *text = g_strdup_printf(_("Unable to rename file:\n%s\nto:\n%s"), filename_from_path(fds->source), filename_from_path(fds->dest)); | |
9 | 2208 file_util_warning_dialog(_("Error renaming file"), text, GTK_STOCK_DIALOG_ERROR, NULL); |
1 | 2209 g_free(text); |
2210 } | |
2211 else | |
2212 { | |
9 | 2213 file_maint_renamed(fds->source, fds->dest); |
1 | 2214 } |
2215 } | |
2216 file_data_single_free(fds); | |
2217 } | |
2218 | |
9 | 2219 static void file_util_rename_single_cb(FileDialog *fd, gpointer data) |
1 | 2220 { |
9 | 2221 const gchar *name; |
2222 gchar *path; | |
2223 | |
2224 name = gtk_entry_get_text(GTK_ENTRY(fd->entry)); | |
2225 path = concat_dir_and_file(fd->dest_path, name); | |
2226 | |
2227 if (strlen(name) == 0 || strcmp(fd->source_path, path) == 0) | |
1 | 2228 { |
9 | 2229 g_free(path); |
1 | 2230 return; |
2231 } | |
2232 | |
9 | 2233 file_util_rename_single(file_data_single_new(fd->source_path, path, fd->type)); |
2234 | |
2235 g_free(path); | |
2236 file_dialog_close(fd); | |
1 | 2237 } |
2238 | |
9 | 2239 static void file_util_rename_single_close_cb(FileDialog *fd, gpointer data) |
2240 { | |
2241 file_dialog_close(fd); | |
2242 } | |
2243 | |
2244 static void file_util_rename_single_do(const gchar *source_path, GtkWidget *parent) | |
1 | 2245 { |
2246 FileDialog *fd; | |
9 | 2247 GtkWidget *table; |
2248 | |
2249 fd = file_util_file_dlg(_("Rename - GQview"), "GQview", "dlg_rename", parent, | |
2250 file_util_rename_single_close_cb, NULL); | |
2251 | |
2252 generic_dialog_add_message(GENERIC_DIALOG(fd), NULL, _("Rename file"), NULL); | |
2253 generic_dialog_add_image(GENERIC_DIALOG(fd), source_path, NULL, NULL, NULL, FALSE); | |
2254 | |
2255 file_dialog_add_button(fd, GTK_STOCK_OK, _("_Rename"), file_util_rename_single_cb, TRUE); | |
1 | 2256 |
2257 fd->source_path = g_strdup(source_path); | |
2258 fd->dest_path = remove_level_from_path(source_path); | |
2259 | |
9 | 2260 table = pref_table_new(GENERIC_DIALOG(fd)->vbox, 2, 2, FALSE, FALSE); |
2261 | |
2262 pref_table_label(table, 0, 0, _("Original name:"), 1.0); | |
2263 pref_table_label(table, 1, 0, filename_from_path(fd->source_path), 0.0); | |
2264 | |
2265 pref_table_label(table, 0, 1, _("New name:"), 1.0); | |
2266 | |
1 | 2267 fd->entry = gtk_entry_new(); |
9 | 2268 gtk_table_attach(GTK_TABLE(table), fd->entry, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, FALSE, 0, 0); |
2269 gtk_entry_set_text(GTK_ENTRY(fd->entry), filename_from_path(fd->source_path)); | |
2270 gtk_editable_select_region(GTK_EDITABLE(fd->entry), 0, strlen(gtk_entry_get_text(GTK_ENTRY(fd->entry)))); | |
2271 generic_dialog_attach_default(GENERIC_DIALOG(fd), fd->entry); | |
1 | 2272 gtk_widget_grab_focus(fd->entry); |
2273 gtk_widget_show(fd->entry); | |
9 | 2274 |
2275 gtk_widget_show(GENERIC_DIALOG(fd)->dialog); | |
1 | 2276 } |
2277 | |
9 | 2278 void file_util_rename(const gchar *source_path, GList *source_list, GtkWidget *parent) |
1 | 2279 { |
2280 if (!source_path && !source_list) return; | |
2281 | |
2282 if (source_path) | |
2283 { | |
9 | 2284 file_util_rename_single_do(source_path, parent); |
1 | 2285 } |
2286 else if (!source_list->next) | |
2287 { | |
9 | 2288 file_util_rename_single_do(source_list->data, parent); |
2289 path_list_free(source_list); | |
1 | 2290 } |
2291 else | |
2292 { | |
9 | 2293 file_util_rename_multiple_do(source_list, parent); |
1 | 2294 } |
2295 } | |
2296 | |
2297 /* | |
2298 *-------------------------------------------------------------------------- | |
2299 * Create directory routines | |
2300 *-------------------------------------------------------------------------- | |
2301 */ | |
2302 | |
9 | 2303 static void file_util_create_dir_do(const gchar *base, const gchar *name) |
1 | 2304 { |
9 | 2305 gchar *path; |
2306 | |
2307 path = concat_dir_and_file(base, name); | |
2308 | |
2309 if (isdir(path)) | |
1 | 2310 { |
9 | 2311 gchar *text = g_strdup_printf(_("The folder:\n%s\nalready exists."), name); |
2312 file_util_warning_dialog(_("Folder exists"), text, GTK_STOCK_DIALOG_INFO, NULL); | |
1 | 2313 g_free(text); |
2314 } | |
9 | 2315 else if (isname(path)) |
1 | 2316 { |
9 | 2317 gchar *text = g_strdup_printf(_("The path:\n%s\nalready exists as a file."), name); |
2318 file_util_warning_dialog(_("Could not create folder"), text, GTK_STOCK_DIALOG_INFO, NULL); | |
1 | 2319 g_free(text); |
2320 } | |
2321 else | |
2322 { | |
9 | 2323 if (!mkdir_utf8(path, 0755)) |
1 | 2324 { |
9 | 2325 gchar *text = g_strdup_printf(_("Unable to create folder:\n%s"), name); |
2326 file_util_warning_dialog(_("Error creating folder"), text, GTK_STOCK_DIALOG_ERROR, NULL); | |
1 | 2327 g_free(text); |
2328 } | |
2329 } | |
9 | 2330 |
2331 g_free(path); | |
1 | 2332 } |
2333 | |
9 | 2334 static void file_util_create_dir_cb(FileDialog *fd, gpointer data) |
1 | 2335 { |
9 | 2336 const gchar *name; |
2337 | |
2338 name = gtk_entry_get_text(GTK_ENTRY(fd->entry)); | |
1 | 2339 |
2340 if (strlen(name) == 0) return; | |
2341 | |
9 | 2342 if (name[0] == '/') |
2343 { | |
2344 gchar *buf; | |
2345 buf = remove_level_from_path(name); | |
2346 file_util_create_dir_do(buf, filename_from_path(name)); | |
2347 g_free(buf); | |
2348 } | |
2349 else | |
2350 { | |
2351 file_util_create_dir_do(fd->dest_path, name); | |
2352 } | |
2353 | |
2354 file_dialog_close(fd); | |
1 | 2355 } |
2356 | |
9 | 2357 static void file_util_create_dir_close_cb(FileDialog *fd, gpointer data) |
2358 { | |
2359 file_dialog_close(fd); | |
2360 } | |
2361 | |
2362 void file_util_create_dir(const gchar *path, GtkWidget *parent) | |
1 | 2363 { |
2364 FileDialog *fd; | |
2365 gchar *text; | |
2366 | |
2367 if (!isdir(path)) return; | |
9 | 2368 |
2369 fd = file_util_file_dlg(_("New folder - GQview"), "GQview", "dlg_newdir", parent, | |
2370 file_util_create_dir_close_cb, NULL); | |
2371 | |
2372 text = g_strdup_printf(_("Create folder in:\n%s\nnamed:"), path); | |
2373 generic_dialog_add_message(GENERIC_DIALOG(fd), NULL, NULL, text); | |
1 | 2374 g_free(text); |
2375 | |
9 | 2376 file_dialog_add_button(fd, GTK_STOCK_OK, NULL, file_util_create_dir_cb, TRUE); |
2377 | |
2378 fd->dest_path = g_strdup(path); | |
1 | 2379 |
2380 fd->entry = gtk_entry_new(); | |
9 | 2381 gtk_box_pack_start(GTK_BOX(GENERIC_DIALOG(fd)->vbox), fd->entry, FALSE, FALSE, 0); |
2382 generic_dialog_attach_default(GENERIC_DIALOG(fd), fd->entry); | |
1 | 2383 gtk_widget_grab_focus(fd->entry); |
2384 gtk_widget_show(fd->entry); | |
9 | 2385 |
2386 gtk_widget_show(GENERIC_DIALOG(fd)->dialog); | |
1 | 2387 } |
2388 |