comparison src/utilops.c @ 9:d907d608745f

Sync to GQview 1.5.9 release. ######## DO NOT BASE ENHANCEMENTS OR TRANSLATION UPDATES ON CODE IN THIS CVS! This CVS is never up to date with current development and is provided solely for reference purposes, please use the latest official release package when making any changes or translation updates. ########
author gqview
date Sat, 26 Feb 2005 00:13:35 +0000
parents c0e337a01cb7
children 3263965d5f9e
comparison
equal deleted inserted replaced
8:e0d0593d519e 9:d907d608745f
1 /* 1 /*
2 * GQview image viewer 2 * GQview
3 * (C)2000 John Ellis 3 * (C) 2004 John Ellis
4 * 4 *
5 * Author: John Ellis 5 * Author: John Ellis
6 * 6 *
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!
7 */ 10 */
8 11
12
9 #include "gqview.h" 13 #include "gqview.h"
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
10 84
11 enum { 85 enum {
12 DIALOG_NEW_DIR, 86 DIALOG_NEW_DIR,
13 DIALOG_COPY, 87 DIALOG_COPY,
14 DIALOG_MOVE, 88 DIALOG_MOVE,
26 GList *source_next; 100 GList *source_next;
27 gchar *dest_base; 101 gchar *dest_base;
28 gchar *source; 102 gchar *source;
29 gchar *dest; 103 gchar *dest;
30 gint copy; 104 gint copy;
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;
31 }; 115 };
32 116
33 typedef struct _FileDataSingle FileDataSingle; 117 typedef struct _FileDataSingle FileDataSingle;
34 struct _FileDataSingle 118 struct _FileDataSingle
35 { 119 {
36 gint confirmed; 120 gint confirmed;
37 gchar *source; 121 gchar *source;
38 gchar *dest; 122 gchar *dest;
39 gint copy; 123 gint copy;
124
125 gint rename;
126 gint rename_auto;
127
128 GtkWidget *rename_box;
129 GtkWidget *rename_entry;
130 GtkWidget *rename_auto_box;
40 }; 131 };
41 132
42 static FileDataMult *file_data_multiple_new(GList *source_list, gchar *dest, gint copy); 133 /*
43 static void file_data_multiple_free(FileDataMult *fdm); 134 *--------------------------------------------------------------------------
44 static void file_util_move_multiple(FileDataMult *fdm); 135 * Adds 1 or 2 images (if 2, side by side) to a GenericDialog
45 static void file_util_move_multiple_ok_cb(GtkWidget *widget, gpointer data); 136 *--------------------------------------------------------------------------
46 static void file_util_move_multiple_all_cb(GtkWidget *widget, gpointer data); 137 */
47 static void file_util_move_multiple_skip_cb(GtkWidget *widget, gpointer data); 138
48 static void file_util_move_multiple_cancel_cb(GtkWidget *widget, gpointer data); 139 #define DIALOG_DEF_IMAGE_DIM_X 200
49 static void file_util_move_multiple(FileDataMult *fdm); 140 #define DIALOG_DEF_IMAGE_DIM_Y 150
50 141
51 static FileDataSingle *file_data_single_new(gchar *source, gchar *dest, gint copy); 142 static void generic_dialog_add_image(GenericDialog *gd, const gchar *path1, const gchar *header1,
52 static void file_data_single_free(FileDataSingle *fds); 143 const gchar *path2, const gchar *header2,
53 static void file_util_move_single_ok_cb(GtkWidget *widget, gpointer data); 144 gint show_filename)
54 static void file_util_move_single(FileDataSingle *fds); 145 {
55 static void file_util_move_single_cancel_cb(GtkWidget *widget, gpointer data); 146 ImageWindow *imd;
56 static void file_util_move_do(FileDialog *fd); 147 GtkWidget *hbox = NULL;
57 static void file_util_move_check(FileDialog *fd); 148 GtkWidget *vbox;
58 static void file_util_move_cb(GtkWidget *widget, gpointer data); 149 GtkWidget *label = NULL;
59 static void file_util_move_enter_cb(gchar *path, gpointer data); 150
60 static void file_util_move_completion_sync_cb(gchar *path, gpointer data); 151 if (path2)
61 static void real_file_util_move(gchar *source_path, GList *source_list, gchar *dest_path, gint copy); 152 {
62 153 hbox = pref_box_new(gd->vbox, TRUE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
63 static void file_util_delete_multiple_ok_cb(GtkWidget *w, gpointer data); 154 }
64 static void file_util_delete_multiple_cancel_cb(GtkWidget *w, gpointer data); 155
65 static void file_util_delete_multiple(GList *source_list); 156 /* image 1 */
66 static void file_util_delete_ok_cb(GtkWidget *w, gpointer data); 157
67 static void file_util_delete_cancel_cb(GtkWidget *w, gpointer data); 158 vbox = gtk_vbox_new(FALSE, PREF_PAD_GAP);
68 static void file_util_delete_single(gchar *path); 159 if (hbox)
69 160 {
70 static void file_util_rename_multiple_ok_cb(GtkWidget *w, gpointer data); 161 GtkWidget *sep;
71 static void file_util_rename_multiple_cancel_cb(GtkWidget *w, gpointer data); 162
72 static void file_util_rename_multiple(FileDialog *fd); 163 gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
73 static void file_util_rename_multiple_cb(GtkWidget *w, gpointer data); 164
74 static void file_util_rename_multiple_select_cb(GtkWidget *clist, 165 sep = gtk_vseparator_new();
75 gint row, gint column, GdkEventButton *bevent, gpointer data); 166 gtk_box_pack_start(GTK_BOX(hbox), sep, FALSE, FALSE, 0);
76 static void file_util_rename_multiple_do(GList *source_list); 167 gtk_widget_show(sep);
77 168 }
78 static void file_util_rename_single_ok_cb(GtkWidget *w, gpointer data); 169 else
79 static void file_util_rename_single_cancel_cb(GtkWidget *w, gpointer data); 170 {
80 static void file_util_rename_single(FileDataSingle *fds); 171 gtk_box_pack_start(GTK_BOX(gd->vbox), vbox, TRUE, TRUE, PREF_PAD_GAP);
81 static void file_util_rename_single_cb(GtkWidget *w, gpointer data); 172 }
82 static void file_util_rename_single_do(gchar *source_path); 173 gtk_widget_show(vbox);
83 174
84 static void file_util_create_dir_do(gchar *source, gchar *path); 175 if (header1)
85 static void file_util_create_dir_cb(GtkWidget *w, gpointer data); 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 }
86 302
87 /* 303 /*
88 *-------------------------------------------------------------------------- 304 *--------------------------------------------------------------------------
89 * Move and Copy routines 305 * Move and Copy routines
90 *-------------------------------------------------------------------------- 306 *--------------------------------------------------------------------------
92 308
93 /* 309 /*
94 * Multi file move 310 * Multi file move
95 */ 311 */
96 312
97 static FileDataMult *file_data_multiple_new(GList *source_list, gchar *dest, gint copy) 313 static FileDataMult *file_data_multiple_new(GList *source_list, const gchar *dest, gint copy)
98 { 314 {
99 FileDataMult *fdm = g_new0(FileDataMult, 1); 315 FileDataMult *fdm = g_new0(FileDataMult, 1);
100 fdm->confirm_all = FALSE; 316 fdm->confirm_all = FALSE;
101 fdm->confirmed = FALSE; 317 fdm->confirmed = FALSE;
102 fdm->skip = FALSE; 318 fdm->skip = FALSE;
109 return fdm; 325 return fdm;
110 } 326 }
111 327
112 static void file_data_multiple_free(FileDataMult *fdm) 328 static void file_data_multiple_free(FileDataMult *fdm)
113 { 329 {
114 free_selected_list(fdm->source_list); 330 path_list_free(fdm->source_list);
115 g_free(fdm->dest_base); 331 g_free(fdm->dest_base);
116 g_free(fdm->dest); 332 g_free(fdm->dest);
117 g_free(fdm); 333 g_free(fdm);
118 } 334 }
119 335
120 static void file_util_move_multiple_ok_cb(GtkWidget *widget, gpointer data) 336 static void file_util_move_multiple(FileDataMult *fdm);
337
338 static void file_util_move_multiple_ok_cb(GenericDialog *gd, gpointer data)
121 { 339 {
122 FileDataMult *fdm = data; 340 FileDataMult *fdm = data;
341
342 fdm->confirmed = TRUE;
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
378 file_util_move_multiple(fdm);
379 }
380
381 static void file_util_move_multiple_all_cb(GenericDialog *gd, gpointer data)
382 {
383 FileDataMult *fdm = data;
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;
407 fdm->confirm_all = TRUE;
408 file_util_move_multiple(fdm);
409 }
410
411 static void file_util_move_multiple_continue_cb(GenericDialog *gd, gpointer data)
412 {
413 FileDataMult *fdm = data;
414
123 fdm->confirmed = TRUE; 415 fdm->confirmed = TRUE;
124 file_util_move_multiple(fdm); 416 file_util_move_multiple(fdm);
125 } 417 }
126 418
127 static void file_util_move_multiple_all_cb(GtkWidget *widget, gpointer data) 419 static void file_util_move_multiple_cancel_cb(GenericDialog *gd, gpointer data)
128 { 420 {
129 FileDataMult *fdm = data; 421 FileDataMult *fdm = data;
130 fdm->confirm_all = TRUE; 422
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); 423 file_data_multiple_free(fdm);
145 } 424 }
146 425
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
147 static void file_util_move_multiple(FileDataMult *fdm) 517 static void file_util_move_multiple(FileDataMult *fdm)
148 { 518 {
149 while (fdm->dest || fdm->source_next) 519 while (fdm->dest || fdm->source_next)
150 { 520 {
521 gint success = FALSE;
522 gint skip_file = FALSE;
523
151 if (!fdm->dest) 524 if (!fdm->dest)
152 { 525 {
153 GList *work = fdm->source_next; 526 GList *work = fdm->source_next;
154 fdm->source = work->data; 527 fdm->source = work->data;
155 fdm->dest = g_strconcat(fdm->dest_base, "/", filename_from_path(fdm->source), NULL); 528 fdm->dest = concat_dir_and_file(fdm->dest_base, filename_from_path(fdm->source));
156 fdm->source_next = work->next; 529 fdm->source_next = work->next;
530 fdm->confirmed = FALSE;
157 } 531 }
158 532
159 if (fdm->dest && fdm->source && strcmp(fdm->dest, fdm->source) == 0) 533 if (fdm->dest && fdm->source && strcmp(fdm->dest, fdm->source) == 0)
160 { 534 {
161 ConfirmDialog *cd; 535 if (!fdm->confirmed)
162 gchar *title;
163 gchar *text;
164 if (fdm->copy)
165 { 536 {
166 title = _("Source to copy matches destination"); 537 GenericDialog *gd;
167 text = g_strdup_printf(_("Unable to copy file:\n%s\nto itself."), fdm->dest); 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;
168 } 562 }
169 else 563 skip_file = TRUE;
564 }
565 else if (isfile(fdm->dest))
566 {
567 if (!fdm->confirmed && !fdm->confirm_all)
170 { 568 {
171 title = _("Source to move matches destination"); 569 GenericDialog *gd;
172 text = g_strdup_printf(_("Unable to move file:\n%s\nto itself."), fdm->dest); 570
571 gd = file_util_move_multiple_confirm_dialog(fdm);
572 gtk_widget_show(gd->dialog);
573 return;
173 } 574 }
174 cd = confirm_dialog_new(title, text, file_util_move_multiple_cancel_cb, fdm); 575 if (fdm->skip) skip_file = TRUE;
175 confirm_dialog_add(cd, _("Continue"), file_util_move_multiple_skip_cb); 576 }
176 g_free(text); 577
177 return; 578 if (skip_file)
178 } 579 {
179 else if (isfile(fdm->dest) && !fdm->confirmed && !fdm->confirm_all && !fdm->skip) 580 success = TRUE;
180 { 581 if (!fdm->confirm_all) fdm->skip = FALSE;
181 ConfirmDialog *cd;
182 gchar *text = g_strdup_printf(_("Overwrite file:\n %s\n with:\b %s"), fdm->dest, fdm->source);
183 cd = confirm_dialog_new_with_image(_("Overwrite file"), text,
184 fdm->dest, fdm->source,
185 file_util_move_multiple_cancel_cb, fdm);
186 confirm_dialog_add(cd, _("Skip"), file_util_move_multiple_skip_cb);
187 confirm_dialog_add(cd, _("Yes to all"), file_util_move_multiple_all_cb);
188 confirm_dialog_add(cd, _("Yes"), file_util_move_multiple_ok_cb);
189 g_free(text);
190 return;
191 } 582 }
192 else 583 else
193 { 584 {
194 gint success = FALSE; 585 gint try = TRUE;
195 if (fdm->skip) 586
587 if (fdm->confirm_all && fdm->rename_all && isfile(fdm->dest))
196 { 588 {
197 success = TRUE; 589 gchar *buf;
198 fdm->skip = FALSE; 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 }
199 } 600 }
200 else 601 if (try)
201 { 602 {
202 if (fdm->copy) 603 if (fdm->copy)
203 { 604 {
204 success = copy_file(fdm->source, fdm->dest); 605 if (copy_file(fdm->source, fdm->dest))
606 {
607 success = TRUE;
608 file_maint_copied(fdm->source, fdm->dest);
609 }
205 } 610 }
206 else 611 else
207 { 612 {
208 if (move_file(fdm->source, fdm->dest)) 613 if (move_file(fdm->source, fdm->dest))
209 { 614 {
210 success = TRUE; 615 success = TRUE;
211 file_is_gone(fdm->source, fdm->source_list); 616 file_maint_moved(fdm->source, fdm->dest, fdm->source_list);
212 } 617 }
213 } 618 }
214 } 619 }
215 if (!success) 620 }
621
622 if (!success)
623 {
624 GenericDialog *gd;
625 const gchar *title;
626 gchar *text;
627
628 if (fdm->copy)
216 { 629 {
217 ConfirmDialog *cd; 630 title = _("Error copying file");
218 gchar *title; 631 text = g_strdup_printf(_("Unable to copy file:\n%s\nto:\n%s\nduring multiple file copy."), fdm->source, fdm->dest);
219 gchar *text;
220 if (fdm->copy)
221 {
222 title = _("Error copying file");
223 text = g_strdup_printf(_("Unable to copy file:\n%sto:\n%s\n during multiple file copy."), fdm->source, fdm->dest);
224 }
225 else
226 {
227 title = _("Error moving file");
228 text = g_strdup_printf(_("Unable to move file:\n%sto:\n%s\n during multiple file move."), fdm->source, fdm->dest);
229 }
230 cd = confirm_dialog_new(title, text, file_util_move_multiple_cancel_cb, fdm);
231 confirm_dialog_add(cd, _("Continue"), file_util_move_multiple_skip_cb);
232 g_free(text);
233 return;
234 } 632 }
235 fdm->confirmed = FALSE; 633 else
236 g_free(fdm->dest); 634 {
237 fdm->dest = NULL; 635 title = _("Error moving file");
238 } 636 text = g_strdup_printf(_("Unable to move file:\n%s\nto:\n%s\nduring multiple file move."), fdm->source, fdm->dest);
637 }
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);
647 }
648
649 g_free(fdm->dest);
650 fdm->dest = NULL;
651
652 if (!success) return;
239 } 653 }
240 654
241 file_data_multiple_free(fdm); 655 file_data_multiple_free(fdm);
242 } 656 }
243 657
244 /* 658 /*
245 * Single file move 659 * Single file move
246 */ 660 */
247 661
248 static FileDataSingle *file_data_single_new(gchar *source, gchar *dest, gint copy) 662 static FileDataSingle *file_data_single_new(const gchar *source, const gchar *dest, gint copy)
249 { 663 {
250 FileDataSingle *fds = g_new0(FileDataSingle, 1); 664 FileDataSingle *fds = g_new0(FileDataSingle, 1);
251 fds->confirmed = FALSE; 665 fds->confirmed = FALSE;
252 fds->source = g_strdup(source); 666 fds->source = g_strdup(source);
253 fds->dest = g_strdup(dest); 667 fds->dest = g_strdup(dest);
260 g_free(fds->source); 674 g_free(fds->source);
261 g_free(fds->dest); 675 g_free(fds->dest);
262 g_free(fds); 676 g_free(fds);
263 } 677 }
264 678
265 static void file_util_move_single_ok_cb(GtkWidget *widget, gpointer data) 679 static void file_util_move_single(FileDataSingle *fds);
680
681 static void file_util_move_single_ok_cb(GenericDialog *gd, gpointer data)
266 { 682 {
267 FileDataSingle *fds = data; 683 FileDataSingle *fds = data;
684
268 fds->confirmed = TRUE; 685 fds->confirmed = TRUE;
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
269 file_util_move_single(fds); 726 file_util_move_single(fds);
270 } 727 }
271 728
272 static void file_util_move_single_cancel_cb(GtkWidget *widget, gpointer data) 729 static void file_util_move_single_cancel_cb(GenericDialog *gd, gpointer data)
273 { 730 {
274 FileDataSingle *fds = data; 731 FileDataSingle *fds = data;
732
275 file_data_single_free(fds); 733 file_data_single_free(fds);
276 } 734 }
277 735
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
278 static void file_util_move_single(FileDataSingle *fds) 770 static void file_util_move_single(FileDataSingle *fds)
279 { 771 {
280 if (fds->dest && fds->source && strcmp(fds->dest, fds->source) == 0) 772 if (fds->dest && fds->source && strcmp(fds->dest, fds->source) == 0)
281 { 773 {
282 warning_dialog(_("Source matches destination"), 774 file_util_warning_dialog(_("Source matches destination"),
283 _("Source and destination are the same, operation cancelled.")); 775 _("Source and destination are the same, operation cancelled."),
776 GTK_STOCK_DIALOG_INFO, NULL);
284 } 777 }
285 else if (isfile(fds->dest) && !fds->confirmed) 778 else if (isfile(fds->dest) && !fds->confirmed)
286 { 779 {
287 ConfirmDialog *cd; 780 GenericDialog *gd;
288 gchar *text = g_strdup_printf(_("Overwrite file:\n%s\n with:\n%s"), fds->dest, fds->source); 781 GtkWidget *hbox;
289 cd = confirm_dialog_new_with_image(_("Overwrite file"), text, 782
290 fds->dest, fds->source, 783 gd = file_util_gen_dlg(_("Overwrite file"), "GQview", "dlg_confirm",
291 file_util_move_single_cancel_cb, fds); 784 NULL, TRUE,
292 confirm_dialog_add(cd, _("Overwrite"), file_util_move_single_ok_cb); 785 file_util_move_single_cancel_cb, fds);
293 g_free(text); 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);
294 return; 823 return;
295 } 824 }
296 else 825 else
297 { 826 {
298 gint success = FALSE; 827 gint success = FALSE;
299 if (fds->copy) 828 if (fds->copy)
300 { 829 {
301 success = copy_file(fds->source, fds->dest); 830 if (copy_file(fds->source, fds->dest))
831 {
832 success = TRUE;
833 file_maint_copied(fds->source, fds->dest);
834 }
302 } 835 }
303 else 836 else
304 { 837 {
305 if (move_file(fds->source, fds->dest)) 838 if (move_file(fds->source, fds->dest))
306 { 839 {
307 success = TRUE; 840 success = TRUE;
308 file_is_gone(fds->source, NULL); 841 file_maint_moved(fds->source, fds->dest, NULL);
309 } 842 }
310 } 843 }
311 if (!success) 844 if (!success)
312 { 845 {
313 gchar *title; 846 gchar *title;
320 else 853 else
321 { 854 {
322 title = _("Error moving file"); 855 title = _("Error moving file");
323 text = g_strdup_printf(_("Unable to move file:\n%s\nto:\n%s"), fds->source, fds->dest); 856 text = g_strdup_printf(_("Unable to move file:\n%s\nto:\n%s"), fds->source, fds->dest);
324 } 857 }
325 warning_dialog(title, text); 858 file_util_warning_dialog(title, text, GTK_STOCK_DIALOG_ERROR, NULL);
326 g_free(text); 859 g_free(text);
327 } 860 }
328 } 861 }
329 862
330 file_data_single_free(fds); 863 file_data_single_free(fds);
334 * file move dialog 867 * file move dialog
335 */ 868 */
336 869
337 static void file_util_move_do(FileDialog *fd) 870 static void file_util_move_do(FileDialog *fd)
338 { 871 {
339 tab_completion_append_to_history(fd->entry, fd->dest_path); 872 file_dialog_sync_history(fd, TRUE);
873
340 if (fd->multiple_files) 874 if (fd->multiple_files)
341 { 875 {
342 file_util_move_multiple(file_data_multiple_new(fd->source_list, fd->dest_path, fd->type)); 876 file_util_move_multiple(file_data_multiple_new(fd->source_list, fd->dest_path, fd->type));
343 fd->source_list = NULL; 877 fd->source_list = NULL;
344 } 878 }
345 else 879 else
346 { 880 {
347 if (isdir(fd->dest_path)) 881 if (isdir(fd->dest_path))
348 { 882 {
349 gchar *buf = g_strconcat(fd->dest_path, "/", filename_from_path(fd->source_path), NULL); 883 gchar *buf = concat_dir_and_file(fd->dest_path, filename_from_path(fd->source_path));
350 g_free(fd->dest_path); 884 gtk_entry_set_text(GTK_ENTRY(fd->entry), buf);
351 fd->dest_path = buf; 885 g_free(buf);
352 } 886 }
353 file_util_move_single(file_data_single_new(fd->source_path, fd->dest_path, fd->type)); 887 file_util_move_single(file_data_single_new(fd->source_path, fd->dest_path, fd->type));
354 } 888 }
355 889
356 generic_dialog_close(NULL, fd); 890 file_dialog_close(fd);
357 } 891 }
358 892
359 static void file_util_move_check(FileDialog *fd) 893 static void file_util_move_check(FileDialog *fd)
360 { 894 {
361 g_free(fd->dest_path);
362 fd->dest_path = remove_trailing_slash(gtk_entry_get_text(GTK_ENTRY(fd->entry)));
363
364 if (fd->multiple_files && !isdir(fd->dest_path)) 895 if (fd->multiple_files && !isdir(fd->dest_path))
365 { 896 {
366 if (isfile(fd->dest_path)) 897 if (isfile(fd->dest_path))
367 warning_dialog(_("Invalid destination"), _("When operating with multiple files, please select\n a directory, not file.")); 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 }
368 else 903 else
369 warning_dialog(_("Invalid directory"), _("Please select an existing directory")); 904 file_util_warning_dialog(_("Invalid folder"),
905 _("Please select an existing folder."),
906 GTK_STOCK_DIALOG_INFO, NULL);
370 return; 907 return;
371 } 908 }
372 909
373 file_util_move_do(fd); 910 file_util_move_do(fd);
374 } 911 }
375 912
376 static void file_util_move_cb(GtkWidget *widget, gpointer data) 913 static void file_util_move_cb(FileDialog *fd, gpointer data)
377 { 914 {
378 FileDialog *fd = data;
379 file_util_move_check(fd); 915 file_util_move_check(fd);
380 } 916 }
381 917
382 static void file_util_move_enter_cb(gchar *path, gpointer data) 918 static void file_util_move_cancel_cb(FileDialog *fd, gpointer data)
383 { 919 {
384 FileDialog *fd = data; 920 file_dialog_close(fd);
385 file_util_move_check(fd); 921 }
386 } 922
387 923 static void real_file_util_move(const gchar *source_path, GList *source_list,
388 static void file_util_move_completion_sync_cb(gchar *path, gpointer data) 924 const gchar *dest_path, gint copy, GtkWidget *parent)
389 {
390 FileDialog *fd = data;
391 destination_widget_sync_to_entry(fd->entry);
392 }
393
394 static void real_file_util_move(gchar *source_path, GList *source_list, gchar *dest_path, gint copy)
395 { 925 {
396 FileDialog *fd; 926 FileDialog *fd;
927 GtkWidget *label;
397 gchar *path = NULL; 928 gchar *path = NULL;
398 gint multiple; 929 gint multiple;
399 gchar *text; 930 const gchar *text;
400 gchar *title; 931 const gchar *title;
401 gchar *op_text; 932 const gchar *op_text;
402 GtkWidget *tabcomp; 933 const gchar *stock_id;
403 GtkWidget *dest;
404 gchar *last_path;
405 934
406 if (!source_path && !source_list) return; 935 if (!source_path && !source_list) return;
407 936
408 if (source_path) 937 if (source_path)
409 { 938 {
415 multiple = TRUE; 944 multiple = TRUE;
416 } 945 }
417 else 946 else
418 { 947 {
419 path = g_strdup(source_list->data); 948 path = g_strdup(source_list->data);
420 free_selected_list(source_list); 949 path_list_free(source_list);
421 source_list = NULL; 950 source_list = NULL;
422 multiple = FALSE; 951 multiple = FALSE;
423 } 952 }
424 953
425 if (copy) 954 if (copy)
426 { 955 {
427 title = _("GQview - copy"); 956 title = _("Copy - GQview");
428 op_text = _("Copy"); 957 op_text = _("_Copy");
429 if (path) 958 if (path)
430 text = g_strdup_printf(_("Copy file:\n%s\nto:"), path); 959 {
960 text = _("Copy file");
961 }
431 else 962 else
432 text = g_strdup_printf(_("Copy multiple files from:\n%s\nto:"), dest_path); 963 {
964 text = _("Copy multiple files");
965 }
966 stock_id = GTK_STOCK_COPY;
433 } 967 }
434 else 968 else
435 { 969 {
436 title = _("GQview - move"); 970 title = _("Move - GQview");
437 op_text = _("Move"); 971 op_text = _("_Move");
438 if (path) 972 if (path)
439 text = g_strdup_printf(_("Move file:\n%s\nto:"), path); 973 {
974 text = _("Move file");
975 }
440 else 976 else
441 text = g_strdup_printf(_("Move multiple files from:\n%s\nto:"), dest_path); 977 {
442 } 978 text = _("Move multiple files");
443 979 }
444 fd = generic_dialog_new(title, text, op_text, _("Cancel"), 980 stock_id = GTK_STOCK_OK;
445 file_util_move_cb, generic_dialog_close); 981 }
446 982
447 g_free(text); 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);
448 1003
449 fd->type = copy; 1004 fd->type = copy;
450 fd->source_path = path; 1005 fd->source_path = path;
451 fd->source_list = source_list; 1006 fd->source_list = source_list;
452 fd->multiple_files = multiple; 1007 fd->multiple_files = multiple;
453 1008
454 tabcomp = tab_completion_new_with_history(&fd->entry, fd->dialog, dest_path, 1009 gtk_widget_show(GENERIC_DIALOG(fd)->dialog);
455 "move_copy", 32, file_util_move_enter_cb, fd); 1010 }
456 last_path = tab_completion_set_to_last_history(fd->entry); 1011
457 if (last_path) 1012 void file_util_move(const gchar *source_path, GList *source_list, const gchar *dest_path, GtkWidget *parent)
458 { 1013 {
459 fd->dest_path = g_strdup(last_path); 1014 real_file_util_move(source_path, source_list, dest_path, FALSE, parent);
460 } 1015 }
461 else 1016
462 { 1017 void file_util_copy(const gchar *source_path, GList *source_list, const gchar *dest_path, GtkWidget *parent)
463 fd->dest_path = g_strdup(dest_path); 1018 {
464 } 1019 real_file_util_move(source_path, source_list, dest_path, TRUE, parent);
465 1020 }
466 /* tabcomp = tab_completion_new(&fd->entry, fd->dialog, fd->dest_path, file_util_move_enter_cb, fd); 1021
467 */ 1022 void file_util_move_simple(GList *list, const gchar *dest_path)
468 gtk_box_pack_start(GTK_BOX(fd->vbox), tabcomp, FALSE, FALSE, 0); 1023 {
469 gtk_widget_show(tabcomp); 1024 if (!list) return;
470 1025 if (!dest_path)
471 gtk_widget_grab_focus(fd->entry); 1026 {
472 1027 path_list_free(list);
473 dest = destination_widget_new(fd->dest_path, fd->entry); 1028 return;
474 1029 }
475 tab_completion_add_tab_func(fd->entry, file_util_move_completion_sync_cb, fd); 1030
476 1031 if (!list->next)
477 gtk_box_pack_start(GTK_BOX(fd->vbox), dest, TRUE, TRUE, 0); 1032 {
478 } 1033 const gchar *source;
479 1034 gchar *dest;
480 void file_util_move(gchar *source_path, GList *source_list, gchar *dest_path) 1035
481 { 1036 source = list->data;
482 real_file_util_move(source_path, source_list, dest_path, FALSE); 1037 dest = concat_dir_and_file(dest_path, filename_from_path(source));
483 } 1038
484 1039 file_util_move_single(file_data_single_new(source, dest, FALSE));
485 void file_util_copy(gchar *source_path, GList *source_list, gchar *dest_path) 1040 g_free(dest);
486 { 1041 path_list_free(list);
487 real_file_util_move(source_path, source_list, dest_path, TRUE); 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)
1052 {
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;
1069 }
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)
1093 {
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;
1104 }
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;
1160 }
1161
1162 static gint file_util_unlink(const gchar *path)
1163 {
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;
1227 }
1228
1229 static void box_append_safe_delete_status(GenericDialog *gd)
1230 {
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);
488 } 1240 }
489 1241
490 /* 1242 /*
491 *-------------------------------------------------------------------------- 1243 *--------------------------------------------------------------------------
492 * Delete routines 1244 * Delete routines
495 1247
496 /* 1248 /*
497 * delete multiple files 1249 * delete multiple files
498 */ 1250 */
499 1251
500 static void file_util_delete_multiple_ok_cb(GtkWidget *w, gpointer data) 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)
501 { 1256 {
502 GList *source_list = data; 1257 GList *source_list = data;
503 1258
504 while(source_list) 1259 while (source_list)
505 { 1260 {
506 gchar *path = source_list->data; 1261 gchar *path = source_list->data;
1262
507 source_list = g_list_remove(source_list, path); 1263 source_list = g_list_remove(source_list, path);
508 if (unlink (path) < 0) 1264
509 { 1265 if (!file_util_unlink(path))
510 ConfirmDialog *cd; 1266 {
511 gchar *text;
512 if (source_list) 1267 if (source_list)
513 { 1268 {
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
514 text = g_strdup_printf(_("Unable to delete file:\n %s\n Continue multiple delete operation?"), path); 1276 text = g_strdup_printf(_("Unable to delete file:\n %s\n Continue multiple delete operation?"), path);
515 cd = confirm_dialog_new(_("Delete failed"), text, file_util_delete_multiple_cancel_cb, source_list); 1277 generic_dialog_add_message(d, GTK_STOCK_DIALOG_WARNING, NULL, text);
516 confirm_dialog_add(cd, _("Continue"), file_util_delete_multiple_ok_cb); 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);
517 } 1283 }
518 else 1284 else
519 { 1285 {
1286 gchar *text;
1287
520 text = g_strdup_printf(_("Unable to delete file:\n%s"), path); 1288 text = g_strdup_printf(_("Unable to delete file:\n%s"), path);
521 warning_dialog(_("Delete failed"), text); 1289 file_util_warning_dialog(_("Delete failed"), text, GTK_STOCK_DIALOG_ERROR, NULL);
1290 g_free(text);
522 } 1291 }
523 g_free(text);
524 g_free(path); 1292 g_free(path);
525 return; 1293 return;
526 } 1294 }
527 else 1295 else
528 { 1296 {
529 file_is_gone(path, source_list); 1297 file_maint_removed(path, source_list);
530 } 1298 }
531 g_free(path); 1299 g_free(path);
532 } 1300 }
533 } 1301 }
534 1302
535 static void file_util_delete_multiple_cancel_cb(GtkWidget *w, gpointer data) 1303 static void file_util_delete_multiple_cancel_cb(GenericDialog *gd, gpointer data)
536 { 1304 {
537 GList *source_list = data; 1305 GList *source_list = data;
538 free_selected_list(source_list); 1306
539 } 1307 path_list_free(source_list);
540 1308 }
541 static void file_util_delete_multiple(GList *source_list) 1309
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)
542 { 1402 {
543 if (!confirm_delete) 1403 if (!confirm_delete)
544 { 1404 {
545 file_util_delete_multiple_ok_cb(NULL, source_list); 1405 file_util_delete_multiple_ok_cb(NULL, source_list);
546 } 1406 }
547 else 1407 else
548 { 1408 {
549 ConfirmDialog *cd; 1409 GenericDialog *gd;
550 cd = confirm_dialog_new(_("Delete files"), _("About to delete multiple files..."), file_util_delete_multiple_cancel_cb, source_list); 1410 GtkWidget *hbox;
551 confirm_dialog_add(cd, _("Delete"), file_util_delete_multiple_ok_cb); 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);
552 } 1448 }
553 } 1449 }
554 1450
555 /* 1451 /*
556 * delete single file 1452 * delete single file
557 */ 1453 */
558 1454
559 static void file_util_delete_ok_cb(GtkWidget *w, gpointer data) 1455 static void file_util_delete_ok_cb(GenericDialog *gd, gpointer data)
560 { 1456 {
561 gchar *path = data; 1457 gchar *path = data;
562 1458
563 if (unlink (path) < 0) 1459 if (!file_util_unlink(path))
564 { 1460 {
565 gchar *text = g_strdup_printf(_("Unable to delete file:\n%s"), path); 1461 gchar *text = g_strdup_printf(_("Unable to delete file:\n%s"), path);
566 warning_dialog(_("File deletion failed"), text); 1462 file_util_warning_dialog(_("File deletion failed"), text, GTK_STOCK_DIALOG_ERROR, NULL);
567 g_free(text); 1463 g_free(text);
568 } 1464 }
569 else 1465 else
570 { 1466 {
571 file_is_gone(path, NULL); 1467 file_maint_removed(path, NULL);
572 } 1468 }
573 1469
574 g_free(path); 1470 g_free(path);
575 } 1471 }
576 1472
577 static void file_util_delete_cancel_cb(GtkWidget *w, gpointer data) 1473 static void file_util_delete_cancel_cb(GenericDialog *gd, gpointer data)
578 { 1474 {
579 gchar *path = data; 1475 gchar *path = data;
1476
580 g_free(path); 1477 g_free(path);
581 } 1478 }
582 1479
583 static void file_util_delete_single(gchar *path) 1480 static void file_util_delete_single(const gchar *path, GtkWidget *parent)
584 { 1481 {
585 gchar *buf = g_strdup(path); 1482 gchar *buf = g_strdup(path);
586 1483
587 if (!confirm_delete) 1484 if (!confirm_delete)
588 { 1485 {
589 file_util_delete_ok_cb(NULL, buf); 1486 file_util_delete_ok_cb(NULL, buf);
590 } 1487 }
591 else 1488 else
592 { 1489 {
593 ConfirmDialog *cd; 1490 GenericDialog *gd;
594 gchar *text = g_strdup_printf(_("About to delete the file:\n %s"), buf); 1491 GtkWidget *table;
595 cd = confirm_dialog_new(_("Delete file"), text, file_util_delete_cancel_cb, buf); 1492 gchar *base;
596 confirm_dialog_add(cd, _("Delete"), file_util_delete_ok_cb); 1493
597 g_free(text); 1494 gd = file_util_gen_dlg(_("Delete file - GQview"), "GQview", "dlg_confirm",
598 } 1495 parent, TRUE,
599 } 1496 file_util_delete_cancel_cb, buf);
600 1497
601 void file_util_delete(gchar *source_path, GList *source_list) 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);
1518 }
1519 }
1520
1521 void file_util_delete(const gchar *source_path, GList *source_list, GtkWidget *parent)
602 { 1522 {
603 if (!source_path && !source_list) return; 1523 if (!source_path && !source_list) return;
604 1524
605 if (source_path) 1525 if (source_path)
606 { 1526 {
607 file_util_delete_single(source_path); 1527 file_util_delete_single(source_path, parent);
608 } 1528 }
609 else if (!source_list->next) 1529 else if (!source_list->next)
610 { 1530 {
611 file_util_delete_single(source_list->data); 1531 file_util_delete_single(source_list->data, parent);
612 free_selected_list(source_list); 1532 path_list_free(source_list);
613 } 1533 }
614 else 1534 else
615 { 1535 {
616 file_util_delete_multiple(source_list); 1536 file_util_delete_multiple(source_list, parent);
617 } 1537 }
618 } 1538 }
619 1539
620 /* 1540 /*
621 *-------------------------------------------------------------------------- 1541 *--------------------------------------------------------------------------
625 1545
626 /* 1546 /*
627 * rename multiple files 1547 * rename multiple files
628 */ 1548 */
629 1549
630 static void file_util_rename_multiple_ok_cb(GtkWidget *w, gpointer data) 1550 enum {
631 { 1551 RENAME_COLUMN_PATH = 0,
632 FileDialog *fd = data; 1552 RENAME_COLUMN_NAME,
633 if (!GTK_WIDGET_VISIBLE(fd->dialog)) gtk_widget_show(fd->dialog); 1553 RENAME_COLUMN_PREVIEW,
634 fd->type = TRUE; 1554 RENAME_COLUMN_COUNT
635 file_util_rename_multiple(fd); 1555 };
636 } 1556
637 1557 typedef struct _RenameDataMult RenameDataMult;
638 static void file_util_rename_multiple_cancel_cb(GtkWidget *w, gpointer data) 1558 struct _RenameDataMult
639 { 1559 {
640 FileDialog *fd = data; 1560 FileDialog *fd;
641 if (!GTK_WIDGET_VISIBLE(fd->dialog)) gtk_widget_show(fd->dialog); 1561
642 return; 1562 gint rename_auto;
643 } 1563
644 1564 GtkWidget *listview;
645 static void file_util_rename_multiple(FileDialog *fd) 1565 GtkWidget *button_auto;
646 { 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);
1594 }
1595
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)
1606 {
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;
1628 }
1629
1630 static void file_util_rename_multiple(RenameDataMult *rd)
1631 {
1632 FileDialog *fd;
1633
1634 fd = rd->fd;
1635
647 if (isfile(fd->dest_path) && !fd->type) 1636 if (isfile(fd->dest_path) && !fd->type)
648 { 1637 {
649 ConfirmDialog *cd; 1638 GenericDialog *gd;
650 gchar *text = g_strdup_printf(_("Overwrite file:\n%s\nby renaming:\n%s"), fd->dest_path, fd->source_path); 1639
651 cd = confirm_dialog_new_with_image(_("Overwrite file"), text, 1640 gd = file_util_gen_dlg(_("Overwrite file"), "GQview", "dlg_confirm",
652 fd->dest_path, fd->source_path, 1641 NULL, TRUE,
653 file_util_rename_multiple_cancel_cb, fd); 1642 file_util_rename_multiple_cancel_cb, rd);
654 confirm_dialog_add(cd, _("Overwrite"), file_util_rename_multiple_ok_cb); 1643
655 g_free(text); 1644 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION,
656 gtk_widget_hide(fd->dialog); 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);
657 return; 1655 return;
658 } 1656 }
659 else 1657 else
660 { 1658 {
661 if (rename (fd->source_path, fd->dest_path) < 0) 1659 if (!rename_file(fd->source_path, fd->dest_path))
662 { 1660 {
663 gchar *text = g_strdup_printf(_("Unable to rename file:\n%s\n to:\n%s"), filename_from_path(fd->source_path), filename_from_path(fd->dest_path)); 1661 gchar *text = g_strdup_printf(_("Unable to rename file:\n%s\n to:\n%s"),
664 warning_dialog(_("Error renaming file"), text); 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);
665 g_free(text); 1665 g_free(text);
666 } 1666 }
667 else 1667 else
668 { 1668 {
1669 GtkTreeModel *store;
1670 GtkTreeIter iter;
1671 GtkTreeIter next;
669 gint row; 1672 gint row;
670 gint n; 1673
671 GtkWidget *clist; 1674 file_maint_renamed(fd->source_path, fd->dest_path);
672 gchar *path; 1675
673 1676 store = gtk_tree_view_get_model(GTK_TREE_VIEW(rd->listview));
674 file_is_renamed(fd->source_path, fd->dest_path); 1677 row = file_util_rename_multiple_find_row(rd, rd->fd->source_path, &iter);
675 1678
676 clist = gtk_object_get_user_data(GTK_OBJECT(fd->entry)); 1679 if (row >= 0 &&
677 path = gtk_object_get_user_data(GTK_OBJECT(clist)); 1680 (gtk_tree_model_iter_nth_child(store, &next, NULL, row + 1) ||
678 row = gtk_clist_find_row_from_data(GTK_CLIST(clist), path); 1681 (row > 0 && gtk_tree_model_iter_nth_child(store, &next, NULL, row - 1)) ) )
679
680 n = g_list_length(GTK_CLIST(clist)->row_list);
681 if (debug) printf("r=%d n=%d\n", row, n);
682 if (n - 1 > row)
683 n = row;
684 else if (n > 1)
685 n = row - 1;
686 else
687 n = -1;
688
689 if (n >= 0)
690 { 1682 {
691 gtk_object_set_user_data(GTK_OBJECT(clist), NULL); 1683 GtkTreeSelection *selection;
692 gtk_clist_remove(GTK_CLIST(clist), row); 1684
693 gtk_clist_select_row(GTK_CLIST(clist), n, -1); 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);
694 } 1688 }
695 else 1689 else
696 { 1690 {
697 if (debug) printf("closed by #%d\n", n); 1691 if (debug) printf("closed by #%d\n", row);
698 generic_dialog_close(NULL, fd); 1692
1693 file_dialog_close(rd->fd);
699 } 1694 }
700 } 1695 }
701 } 1696 }
702 } 1697 }
703 1698
704 static void file_util_rename_multiple_cb(GtkWidget *w, gpointer data) 1699 static void file_util_rename_multiple_auto(RenameDataMult *rd)
705 { 1700 {
706 FileDialog *fd = data; 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--;
1807 gtk_spin_button_set_value(GTK_SPIN_BUTTON(rd->auto_spin_start), (float)n);
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;
707 gchar *base; 1822 gchar *base;
708 gchar *name; 1823 const gchar *name;
709 1824
710 name = gtk_entry_get_text(GTK_ENTRY(fd->entry)); 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));
711 base = remove_level_from_path(fd->source_path); 1832 base = remove_level_from_path(fd->source_path);
1833
712 g_free(fd->dest_path); 1834 g_free(fd->dest_path);
713 fd->dest_path = g_strconcat(base, "/", name, NULL); 1835 fd->dest_path = concat_dir_and_file(base, name);
714 g_free(base); 1836 g_free(base);
715 1837
716 if (strlen(name) == 0 || strcmp(fd->source_path, fd->dest_path) == 0) 1838 if (strlen(name) == 0 || strcmp(fd->source_path, fd->dest_path) == 0)
717 { 1839 {
718 return; 1840 return;
719 } 1841 }
720 1842
721 fd->type = FALSE; 1843 fd->type = FALSE;
722 file_util_rename_multiple(fd); 1844 file_util_rename_multiple(rd);
723 } 1845 }
724 1846
725 static void file_util_rename_multiple_select_cb(GtkWidget *clist, 1847 static void file_util_rename_multiple_close_cb(FileDialog *fd, gpointer data)
726 gint row, gint column, GdkEventButton *bevent, gpointer data) 1848 {
727 { 1849 RenameDataMult *rd = data;
728 FileDialog *fd = data; 1850
1851 file_dialog_close(rd->fd);
1852 }
1853
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)
1884 {
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
1914 }
1915
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)
1950 {
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;
729 GtkWidget *label; 1975 GtkWidget *label;
730 gchar *name; 1976
731 gchar *path; 1977 vbox = gtk_vbox_new(FALSE, 0);
732 1978 gtk_box_pack_start(GTK_BOX(box), vbox, expand, expand, 0);
733 label = gtk_object_get_user_data(GTK_OBJECT(fd->dialog)); 1979 gtk_widget_show(vbox);
734 path = gtk_clist_get_row_data(GTK_CLIST(clist), row); 1980
735 g_free(fd->source_path); 1981 label = gtk_label_new(text);
736 fd->source_path = g_strdup(path); 1982 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
737 gtk_object_set_user_data(GTK_OBJECT(clist), path); 1983 gtk_widget_show(label);
738 name = filename_from_path(fd->source_path); 1984
739 1985 return vbox;
740 gtk_label_set(GTK_LABEL(label), name); 1986 }
741 gtk_entry_set_text(GTK_ENTRY(fd->entry), name); 1987
742 1988 static GtkTreeViewColumn *file_util_rename_multiple_add_column(RenameDataMult *rd, const gchar *text, gint n)
743 gtk_widget_grab_focus(fd->entry); 1989 {
744 } 1990 GtkTreeViewColumn *column;
745 1991 GtkCellRenderer *renderer;
746 static void file_util_rename_multiple_do(GList *source_list) 1992
747 { 1993 column = gtk_tree_view_column_new();
748 FileDialog *fd; 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;
749 GtkWidget *scrolled; 2018 GtkWidget *scrolled;
750 GtkWidget *clist; 2019 GtkListStore *store;
751 GtkWidget *label; 2020 GtkTreeSelection *selection;
2021 GtkTreeViewColumn *column;
2022 GtkWidget *hbox;
2023 GtkWidget *vbox;
2024 GtkWidget *box2;
2025 GtkWidget *table;
2026 GtkWidget *combo;
752 GList *work; 2027 GList *work;
753 2028
754 fd = generic_dialog_new(_("GQview - rename"), _("Rename multiple files:"), _("Rename"), _("Cancel"), 2029 rd = g_new0(RenameDataMult, 1);
755 file_util_rename_multiple_cb, generic_dialog_close); 2030
756 2031 rd->fd = file_util_file_dlg(_("Rename - GQview"),
757 fd->source_path = g_strdup(source_list->data); 2032 "GQview", "dlg_rename", parent,
758 fd->dest_path = NULL; 2033 file_util_rename_multiple_close_cb, rd);
759 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
760 scrolled = gtk_scrolled_window_new(NULL, NULL); 2048 scrolled = gtk_scrolled_window_new(NULL, NULL);
761 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), 2049 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
762 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); 2050 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled),
763 gtk_box_pack_start(GTK_BOX(fd->vbox), scrolled, TRUE, TRUE, 0); 2051 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
2052 gtk_paned_pack1(GTK_PANED(pane), scrolled, TRUE, TRUE);
764 gtk_widget_show(scrolled); 2053 gtk_widget_show(scrolled);
765 2054
766 clist=gtk_clist_new (1); 2055 store = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
767 gtk_clist_set_column_auto_resize(GTK_CLIST(clist), 0, TRUE); 2056 rd->listview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
768 gtk_signal_connect (GTK_OBJECT (clist), "select_row",(GtkSignalFunc) file_util_rename_multiple_select_cb, fd); 2057 g_object_unref(store);
769 gtk_widget_set_usize(clist, 250, 150); 2058
770 gtk_container_add (GTK_CONTAINER (scrolled), clist); 2059 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(rd->listview), TRUE);
771 gtk_widget_show (clist); 2060 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(rd->listview), FALSE);
772 2061
773 gtk_object_set_user_data(GTK_OBJECT(clist), source_list->data); 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);
774 2077
775 work = source_list; 2078 work = source_list;
776 while(work) 2079 while (work)
777 { 2080 {
778 gint row; 2081 gchar *path = work->data;
779 gchar *buf[2]; 2082 GtkTreeIter iter;
780 buf[0] = filename_from_path(work->data); 2083
781 buf[1] = NULL; 2084 gtk_list_store_append(store, &iter);
782 row = gtk_clist_append(GTK_CLIST(clist), buf); 2085 gtk_list_store_set(store, &iter, RENAME_COLUMN_PATH, path, RENAME_COLUMN_NAME, filename_from_path(path), -1);
783 gtk_clist_set_row_data_full(GTK_CLIST(clist), row, 2086
784 work->data, (GtkDestroyNotify) g_free);
785 work = work->next; 2087 work = work->next;
786 } 2088 }
787 2089
788 g_list_free(source_list); 2090 path_list_free(source_list);
789 2091
790 label = gtk_label_new(_("Rename:")); 2092 rd->imd = image_new(TRUE);
791 gtk_box_pack_start(GTK_BOX(fd->vbox), label, FALSE, FALSE, 0); 2093 gtk_widget_set_size_request(rd->imd->widget, DIALOG_DEF_IMAGE_DIM_X, DIALOG_DEF_IMAGE_DIM_Y);
792 gtk_widget_show(label); 2094 gtk_paned_pack2(GTK_PANED(pane), rd->imd->widget, FALSE, TRUE);
793 2095 gtk_widget_show(rd->imd->widget);
794 label = gtk_label_new(filename_from_path(fd->source_path)); 2096
795 gtk_box_pack_start(GTK_BOX(fd->vbox), label, FALSE, FALSE, 0); 2097 hbox = gtk_hbox_new(FALSE, 0);
796 gtk_widget_show(label); 2098 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
797 gtk_object_set_user_data(GTK_OBJECT(fd->dialog), label); 2099 gtk_widget_show(hbox);
798 2100
799 label = gtk_label_new(_("to:")); 2101 rd->button_auto = gtk_check_button_new_with_label(_("Auto rename"));
800 gtk_box_pack_start(GTK_BOX(fd->vbox), label, FALSE, FALSE, 0); 2102 g_signal_connect(G_OBJECT(rd->button_auto), "clicked",
801 gtk_widget_show(label); 2103 G_CALLBACK(file_util_rename_mulitple_auto_toggle), rd);
802 2104 gtk_box_pack_end(GTK_BOX(hbox), rd->button_auto, FALSE, FALSE, 0);
803 fd->entry = gtk_entry_new(); 2105 gtk_widget_show(rd->button_auto);
804 gtk_entry_set_text(GTK_ENTRY(fd->entry), filename_from_path(fd->source_path)); 2106
805 gtk_box_pack_start(GTK_BOX(fd->vbox), fd->entry, FALSE, FALSE, 0); 2107 rd->rename_box = pref_box_new(vbox, FALSE, GTK_ORIENTATION_VERTICAL, 0);
806 gtk_widget_grab_focus(fd->entry); 2108 table = pref_table_new(rd->rename_box, 2, 2, FALSE, FALSE);
807 gtk_widget_show(fd->entry); 2109
808 2110 pref_table_label(table, 0, 0, _("Original name:"), 1.0);
809 gtk_object_set_user_data(GTK_OBJECT(fd->entry), clist); 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);
810 } 2160 }
811 2161
812 /* 2162 /*
813 * rename single file 2163 * rename single file
814 */ 2164 */
815 2165
816 static void file_util_rename_single_ok_cb(GtkWidget *w, gpointer data) 2166 static void file_util_rename_single(FileDataSingle *fds);
2167
2168 static void file_util_rename_single_ok_cb(GenericDialog *gd, gpointer data)
817 { 2169 {
818 FileDataSingle *fds = data; 2170 FileDataSingle *fds = data;
819 fds->confirmed = TRUE; 2171 fds->confirmed = TRUE;
820 file_util_rename_single(fds); 2172 file_util_rename_single(fds);
821 } 2173 }
822 2174
823 static void file_util_rename_single_cancel_cb(GtkWidget *w, gpointer data) 2175 static void file_util_rename_single_cancel_cb(GenericDialog *gd, gpointer data)
824 { 2176 {
825 FileDataSingle *fds = data; 2177 FileDataSingle *fds = data;
826 file_data_single_free(fds); 2178 file_data_single_free(fds);
827 } 2179 }
828 2180
829 static void file_util_rename_single(FileDataSingle *fds) 2181 static void file_util_rename_single(FileDataSingle *fds)
830 { 2182 {
831 if (isfile(fds->dest) && !fds->confirmed) 2183 if (isfile(fds->dest) && !fds->confirmed)
832 { 2184 {
833 ConfirmDialog *cd; 2185 GenericDialog *gd;
834 gchar *text = g_strdup_printf(_("Overwrite file:\n%s\nby renaming:\n%s"), fds->dest,fds->source); 2186
835 cd = confirm_dialog_new_with_image(_("Overwrite file"), text, 2187 gd = file_util_gen_dlg(_("Overwrite file"), "GQview", "dlg_confirm",
836 fds->dest, fds->source, 2188 NULL, TRUE,
837 file_util_rename_single_cancel_cb, fds); 2189 file_util_rename_single_cancel_cb, fds);
838 confirm_dialog_add(cd, _("Overwrite"), file_util_rename_single_ok_cb); 2190
839 g_free(text); 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
840 return; 2201 return;
841 } 2202 }
842 else 2203 else
843 { 2204 {
844 if (rename (fds->source, fds->dest) < 0) 2205 if (!rename_file(fds->source, fds->dest))
845 { 2206 {
846 gchar *text = g_strdup_printf(_("Unable to rename file:\n%s\nto:\n%s"), filename_from_path(fds->source), filename_from_path(fds->dest)); 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));
847 warning_dialog(_("Error renaming file"), text); 2208 file_util_warning_dialog(_("Error renaming file"), text, GTK_STOCK_DIALOG_ERROR, NULL);
848 g_free(text); 2209 g_free(text);
849 } 2210 }
850 else 2211 else
851 { 2212 {
852 file_is_renamed(fds->source, fds->dest); 2213 file_maint_renamed(fds->source, fds->dest);
853 } 2214 }
854 } 2215 }
855 file_data_single_free(fds); 2216 file_data_single_free(fds);
856 } 2217 }
857 2218
858 static void file_util_rename_single_cb(GtkWidget *w, gpointer data) 2219 static void file_util_rename_single_cb(FileDialog *fd, gpointer data)
859 { 2220 {
860 FileDialog *fd = data; 2221 const gchar *name;
861 gchar *name = gtk_entry_get_text(GTK_ENTRY(fd->entry)); 2222 gchar *path;
862 gchar *buf = g_strconcat(fd->dest_path, "/", name, NULL); 2223
863 2224 name = gtk_entry_get_text(GTK_ENTRY(fd->entry));
864 if (strlen(name) == 0 || strcmp(fd->source_path, buf) == 0) 2225 path = concat_dir_and_file(fd->dest_path, name);
865 { 2226
866 g_free(buf); 2227 if (strlen(name) == 0 || strcmp(fd->source_path, path) == 0)
2228 {
2229 g_free(path);
867 return; 2230 return;
868 } 2231 }
869 2232
870 g_free(fd->dest_path); 2233 file_util_rename_single(file_data_single_new(fd->source_path, path, fd->type));
871 fd->dest_path = buf; 2234
872 2235 g_free(path);
873 file_util_rename_single(file_data_single_new(fd->source_path, fd->dest_path, fd->type)); 2236 file_dialog_close(fd);
874 2237 }
875 generic_dialog_close(NULL, fd); 2238
876 } 2239 static void file_util_rename_single_close_cb(FileDialog *fd, gpointer data)
877 2240 {
878 static void file_util_rename_single_do(gchar *source_path) 2241 file_dialog_close(fd);
2242 }
2243
2244 static void file_util_rename_single_do(const gchar *source_path, GtkWidget *parent)
879 { 2245 {
880 FileDialog *fd; 2246 FileDialog *fd;
881 gchar *text; 2247 GtkWidget *table;
882 gchar *name = filename_from_path(source_path); 2248
883 2249 fd = file_util_file_dlg(_("Rename - GQview"), "GQview", "dlg_rename", parent,
884 text = g_strdup_printf(_("Rename file:\n%s\nto:"), name); 2250 file_util_rename_single_close_cb, NULL);
885 fd = generic_dialog_new(_("GQview - rename"), text, _("Rename"), _("Cancel"), 2251
886 file_util_rename_single_cb, generic_dialog_close); 2252 generic_dialog_add_message(GENERIC_DIALOG(fd), NULL, _("Rename file"), NULL);
887 g_free(text); 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);
888 2256
889 fd->source_path = g_strdup(source_path); 2257 fd->source_path = g_strdup(source_path);
890 fd->dest_path = remove_level_from_path(source_path); 2258 fd->dest_path = remove_level_from_path(source_path);
891 2259
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
892 fd->entry = gtk_entry_new(); 2267 fd->entry = gtk_entry_new();
893 gtk_entry_set_text(GTK_ENTRY(fd->entry), name); 2268 gtk_table_attach(GTK_TABLE(table), fd->entry, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, FALSE, 0, 0);
894 gtk_box_pack_start(GTK_BOX(fd->vbox), fd->entry, FALSE, FALSE, 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);
895 gtk_widget_grab_focus(fd->entry); 2272 gtk_widget_grab_focus(fd->entry);
896 gtk_widget_show(fd->entry); 2273 gtk_widget_show(fd->entry);
897 } 2274
898 2275 gtk_widget_show(GENERIC_DIALOG(fd)->dialog);
899 void file_util_rename(gchar *source_path, GList *source_list) 2276 }
2277
2278 void file_util_rename(const gchar *source_path, GList *source_list, GtkWidget *parent)
900 { 2279 {
901 if (!source_path && !source_list) return; 2280 if (!source_path && !source_list) return;
902 2281
903 if (source_path) 2282 if (source_path)
904 { 2283 {
905 file_util_rename_single_do(source_path); 2284 file_util_rename_single_do(source_path, parent);
906 } 2285 }
907 else if (!source_list->next) 2286 else if (!source_list->next)
908 { 2287 {
909 file_util_rename_single_do(source_list->data); 2288 file_util_rename_single_do(source_list->data, parent);
910 free_selected_list(source_list); 2289 path_list_free(source_list);
911 } 2290 }
912 else 2291 else
913 { 2292 {
914 file_util_rename_multiple_do(source_list); 2293 file_util_rename_multiple_do(source_list, parent);
915 } 2294 }
916 } 2295 }
917 2296
918 /* 2297 /*
919 *-------------------------------------------------------------------------- 2298 *--------------------------------------------------------------------------
920 * Create directory routines 2299 * Create directory routines
921 *-------------------------------------------------------------------------- 2300 *--------------------------------------------------------------------------
922 */ 2301 */
923 2302
924 static void file_util_create_dir_do(gchar *source, gchar *path) 2303 static void file_util_create_dir_do(const gchar *base, const gchar *name)
925 { 2304 {
926 if (isfile(path)) 2305 gchar *path;
927 { 2306
928 gchar *text = g_strdup_printf(_("The path:\n%s\nalready exists as a file."), filename_from_path(path)); 2307 path = concat_dir_and_file(base, name);
929 warning_dialog(_("Could not create directory"), text); 2308
2309 if (isdir(path))
2310 {
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);
930 g_free(text); 2313 g_free(text);
931 } 2314 }
932 else if (isdir(path)) 2315 else if (isname(path))
933 { 2316 {
934 gchar *text = g_strdup_printf(_("The directory:\n%s\nalready exists."), filename_from_path(path)); 2317 gchar *text = g_strdup_printf(_("The path:\n%s\nalready exists as a file."), name);
935 warning_dialog(_("Directory exists"), text); 2318 file_util_warning_dialog(_("Could not create folder"), text, GTK_STOCK_DIALOG_INFO, NULL);
936 g_free(text); 2319 g_free(text);
937 } 2320 }
938 else 2321 else
939 { 2322 {
940 if (mkdir (path, 0755) < 0) 2323 if (!mkdir_utf8(path, 0755))
941 { 2324 {
942 gchar *text = g_strdup_printf(_("Unable to create directory:\n%s"), filename_from_path(path)); 2325 gchar *text = g_strdup_printf(_("Unable to create folder:\n%s"), name);
943 warning_dialog(_("Error creating directory"), text); 2326 file_util_warning_dialog(_("Error creating folder"), text, GTK_STOCK_DIALOG_ERROR, NULL);
944 g_free(text); 2327 g_free(text);
945 } 2328 }
946 else 2329 }
947 { 2330
948 if (strcmp(source, current_path) == 0) 2331 g_free(path);
949 { 2332 }
950 gchar *buf = g_strdup(current_path); 2333
951 filelist_change_to(buf); 2334 static void file_util_create_dir_cb(FileDialog *fd, gpointer data)
952 g_free(buf); 2335 {
953 } 2336 const gchar *name;
954 } 2337
955 } 2338 name = gtk_entry_get_text(GTK_ENTRY(fd->entry));
956 }
957
958 static void file_util_create_dir_cb(GtkWidget *w, gpointer data)
959 {
960 FileDialog *fd = data;
961 gchar *name = gtk_entry_get_text(GTK_ENTRY(fd->entry));
962 2339
963 if (strlen(name) == 0) return; 2340 if (strlen(name) == 0) return;
964 2341
965 g_free(fd->dest_path); 2342 if (name[0] == '/')
966 fd->dest_path = g_strconcat(fd->source_path, "/", name, NULL); 2343 {
967 2344 gchar *buf;
968 file_util_create_dir_do(fd->source_path, fd->dest_path); 2345 buf = remove_level_from_path(name);
969 2346 file_util_create_dir_do(buf, filename_from_path(name));
970 generic_dialog_close(NULL, fd); 2347 g_free(buf);
971 } 2348 }
972 2349 else
973 void file_util_create_dir(gchar *path) 2350 {
2351 file_util_create_dir_do(fd->dest_path, name);
2352 }
2353
2354 file_dialog_close(fd);
2355 }
2356
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)
974 { 2363 {
975 FileDialog *fd; 2364 FileDialog *fd;
976 gchar *text; 2365 gchar *text;
977 gchar *name;
978 2366
979 if (!isdir(path)) return; 2367 if (!isdir(path)) return;
980 name = filename_from_path(path); 2368
981 2369 fd = file_util_file_dlg(_("New folder - GQview"), "GQview", "dlg_newdir", parent,
982 text = g_strdup_printf(_("Create directory in:\n%s\nnamed:"), path); 2370 file_util_create_dir_close_cb, NULL);
983 fd = generic_dialog_new(_("GQview - new directory"), text, _("Create"), _("Cancel"), 2371
984 file_util_create_dir_cb, generic_dialog_close); 2372 text = g_strdup_printf(_("Create folder in:\n%s\nnamed:"), path);
2373 generic_dialog_add_message(GENERIC_DIALOG(fd), NULL, NULL, text);
985 g_free(text); 2374 g_free(text);
986 2375
987 fd->source_path = g_strdup(path); 2376 file_dialog_add_button(fd, GTK_STOCK_OK, NULL, file_util_create_dir_cb, TRUE);
988 fd->dest_path = NULL; 2377
2378 fd->dest_path = g_strdup(path);
989 2379
990 fd->entry = gtk_entry_new(); 2380 fd->entry = gtk_entry_new();
991 gtk_box_pack_start(GTK_BOX(fd->vbox), fd->entry, FALSE, FALSE, 0); 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);
992 gtk_widget_grab_focus(fd->entry); 2383 gtk_widget_grab_focus(fd->entry);
993 gtk_widget_show(fd->entry); 2384 gtk_widget_show(fd->entry);
994 } 2385
995 2386 gtk_widget_show(GENERIC_DIALOG(fd)->dialog);
2387 }
2388