1 /*
2  * UFRaw - Unidentified Flying Raw converter for digital camera images
3  *
4  * ufraw_delete.c - The GUI for choosing what files to delete.
5  * Copyright 2004-2016 by Udi Fuchs
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  */
12 
13 #include "ufraw.h"
14 #include <string.h>
15 #include <glib/gi18n.h>
16 #include <gtk/gtk.h>
17 
18 // Response can be any unique positive integer
19 #define UFRAW_RESPONSE_DELETE_SELECTED 1
20 #define UFRAW_RESPONSE_DELETE_ALL 2
21 
ufraw_delete(void * widget,ufraw_data * uf)22 long ufraw_delete(void *widget, ufraw_data *uf)
23 {
24     if (!g_file_test(uf->filename, G_FILE_TEST_EXISTS)) {
25         char *ufile = g_filename_display_name(uf->filename);
26         ufraw_message(UFRAW_ERROR, _("Raw file '%s' missing."), ufile);
27         g_free(ufile);
28         return UFRAW_ERROR;
29     }
30     GtkDialog *dialog = GTK_DIALOG(gtk_dialog_new_with_buttons(
31                                        _("Delete raw file"), GTK_WINDOW(gtk_widget_get_toplevel(widget)),
32                                        GTK_DIALOG_DESTROY_WITH_PARENT,
33                                        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
34                                        _("_Delete selected"), UFRAW_RESPONSE_DELETE_SELECTED,
35                                        _("Delete _All"), UFRAW_RESPONSE_DELETE_ALL, NULL));
36     gtk_dialog_set_default_response(dialog, GTK_RESPONSE_CANCEL);
37 
38     GtkBox *box = GTK_BOX(dialog->vbox);
39     GtkWidget *label = gtk_label_new(_("Select files to delete"));
40     gtk_box_pack_start(box, label, FALSE, FALSE, 0);
41 
42     char *path = g_path_get_dirname(uf->filename);
43     GDir *dir = g_dir_open(path, 0, NULL);
44     if (dir == NULL) {
45         char *upath = g_filename_display_name(path);
46         ufraw_message(UFRAW_ERROR, _("Error reading directory '%s'."), upath);
47         g_free(upath);
48         g_free(path);
49         return UFRAW_ERROR;
50     }
51     g_free(path);
52 
53     char *dirname = g_path_get_dirname(uf->filename);
54     char *base = g_path_get_basename(uf->filename);
55     if (strcmp(base, uf->filename) == 0) {
56         // Handle empty dirname
57         g_free(dirname);
58         dirname = g_strdup("");
59     }
60     char *rawBase = uf_file_set_type(base, ".");
61     int rawBaseLen = strlen(rawBase);
62     GList *buttonList = NULL;
63     GList *fileList = NULL;
64 
65     // Check button for raw file
66     char *ufile = g_filename_display_name(uf->filename);
67     GtkWidget *button = gtk_check_button_new_with_label(ufile);
68     buttonList = g_list_append(buttonList, button);
69     g_free(ufile);
70     gtk_box_pack_start(box, button, FALSE, FALSE, 0);
71     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
72     fileList = g_list_append(fileList, g_strdup(uf->filename));
73 
74     // Check buttons for associated files
75     const char *file;
76     while ((file = g_dir_read_name(dir)) != NULL) {
77         if (strncmp(file, rawBase, rawBaseLen) == 0 &&
78                 strcmp(file, base) != 0) {
79             char *filename = g_build_filename(dirname, file, NULL);
80             char *ufile = g_filename_display_name(filename);
81             button = gtk_check_button_new_with_label(ufile);
82             buttonList = g_list_append(buttonList, button);
83             g_free(ufile);
84             gtk_box_pack_start(box, button, FALSE, FALSE, 0);
85             gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE);
86             fileList = g_list_append(fileList, filename);
87         }
88     }
89     g_dir_close(dir);
90     gtk_widget_show_all(GTK_WIDGET(dialog));
91     long response = gtk_dialog_run(dialog);
92 
93     long status = UFRAW_CANCEL;
94     /* Delete files as needed */
95     while (fileList != NULL) {
96         if (response == UFRAW_RESPONSE_DELETE_ALL ||
97                 (response == UFRAW_RESPONSE_DELETE_SELECTED &&
98                  gtk_toggle_button_get_active(
99                      GTK_TOGGLE_BUTTON(buttonList->data)))) {
100             if (g_unlink(fileList->data) != 0) {
101                 char *ufile = g_filename_display_name(fileList->data);
102                 ufraw_message(UFRAW_ERROR, _("Error deleting '%s'"), ufile);
103                 g_free(ufile);
104             } else if (strcmp(fileList->data, uf->filename) == 0) {
105                 /* Success means deleting the raw file */
106                 status = UFRAW_SUCCESS;
107             }
108         }
109         g_free(fileList->data);
110         fileList = g_list_next(fileList);
111         buttonList = g_list_next(buttonList);
112     }
113     g_list_free(fileList);
114     g_list_free(buttonList);
115     g_free(base);
116     g_free(dirname);
117     gtk_widget_destroy(GTK_WIDGET(dialog));
118     return status;
119 }
120