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