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