1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 
3 /*
4  *  GThumb
5  *
6  *  Copyright (C) 2005-2009 Free Software Foundation, Inc.
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include <config.h>
23 #include <gtk/gtk.h>
24 #include <gthumb.h>
25 #include "dlg-find-duplicates.h"
26 #include "gth-find-duplicates.h"
27 
28 
29 #define GET_WIDGET(name) _gtk_builder_get_widget (data->builder, (name))
30 
31 
32 typedef struct {
33 	GthBrowser *browser;
34 	GtkBuilder *builder;
35 	GtkWidget  *dialog;
36 	GtkWidget  *location_chooser;
37 	GList      *general_tests;
38 } DialogData;
39 
40 
41 static void
destroy_cb(GtkWidget * widget,DialogData * data)42 destroy_cb (GtkWidget  *widget,
43 	    DialogData *data)
44 {
45 	gth_browser_set_dialog (data->browser, "find_duplicates", NULL);
46 
47 	_g_string_list_free (data->general_tests);
48 	g_object_unref (data->builder);
49 	g_free (data);
50 }
51 
52 
53 static void
ok_clicked_cb(GtkWidget * widget,DialogData * data)54 ok_clicked_cb (GtkWidget  *widget,
55 	       DialogData *data)
56 {
57 	GFile *folder;
58 
59 	folder = gth_location_chooser_get_current (GTH_LOCATION_CHOOSER (data->location_chooser));
60 	if (folder == NULL)
61 		return;
62 
63 	gth_find_duplicates_exec (data->browser,
64 				  folder,
65 				  gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("include_subfolder_checkbutton"))),
66 				  g_list_nth_data (data->general_tests, gtk_combo_box_get_active (GTK_COMBO_BOX (GET_WIDGET ("file_type_combobox")))));
67 
68 	gtk_widget_destroy (data->dialog);
69 }
70 
71 
72 void
dlg_find_duplicates(GthBrowser * browser)73 dlg_find_duplicates (GthBrowser *browser)
74 {
75 	DialogData *data;
76 	GSettings  *settings;
77 	GList      *tests;
78 	char       *general_filter;
79 	int         active_filter;
80 	int         i;
81 	int         i_general;
82 	GList      *scan;
83 
84 	if (gth_browser_get_dialog (browser, "find_duplicates") != NULL) {
85 		gtk_window_present (GTK_WINDOW (gth_browser_get_dialog (browser, "find_duplicates")));
86 		return;
87 	}
88 
89 	data = g_new0 (DialogData, 1);
90 	data->browser = browser;
91 	data->builder = _gtk_builder_new_from_file ("find-duplicates.ui", "find_duplicates");
92 
93 	settings = g_settings_new (GTHUMB_BROWSER_SCHEMA);
94 
95 	/* Get the widgets. */
96 
97 	data->dialog = g_object_new (GTK_TYPE_DIALOG,
98 				     "title", _("Find Duplicates"),
99 				     "use-header-bar", _gtk_settings_get_dialogs_use_header (),
100 				     "resizable", FALSE,
101 				     NULL);
102 
103 	gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (data->dialog))),
104 	                   _gtk_builder_get_widget (data->builder, "dialog_content"));
105 	gtk_dialog_add_buttons (GTK_DIALOG (data->dialog),
106 				_("_Find"), GTK_RESPONSE_OK,
107 				_GTK_LABEL_CANCEL, GTK_RESPONSE_CANCEL,
108 				NULL);
109 	_gtk_dialog_add_class_to_response (GTK_DIALOG (data->dialog), GTK_RESPONSE_OK, GTK_STYLE_CLASS_SUGGESTED_ACTION);
110 
111 	gth_browser_set_dialog (browser, "find_duplicates", data->dialog);
112 	g_object_set_data (G_OBJECT (data->dialog), "dialog_data", data);
113 
114 	data->location_chooser = g_object_new (GTH_TYPE_LOCATION_CHOOSER,
115 					       "show-entry-points", TRUE,
116 					       "show-other", TRUE,
117 					       "relief", GTK_RELIEF_NORMAL,
118 					       NULL);
119 	gtk_widget_show (data->location_chooser);
120 	gtk_container_add (GTK_CONTAINER (GET_WIDGET ("location_chooser_container")), data->location_chooser);
121 
122 	/* Set widgets data. */
123 
124 	gth_location_chooser_set_current (GTH_LOCATION_CHOOSER (data->location_chooser), gth_browser_get_location (browser));
125 
126 	tests = gth_main_get_registered_objects_id (GTH_TYPE_TEST);
127 	general_filter = g_settings_get_string (settings, PREF_BROWSER_GENERAL_FILTER);
128 	active_filter = 0;
129 	for (i = 0, i_general = -1, scan = tests; scan; scan = scan->next, i++) {
130 		const char  *registered_test_id = scan->data;
131 		GthTest     *test;
132 		GtkTreeIter  iter;
133 
134 		if (strncmp (registered_test_id, "file::type::", 12) != 0)
135 			continue;
136 
137 		i_general += 1;
138 
139 		if (strcmp (registered_test_id, general_filter) == 0)
140 			active_filter = i_general;
141 
142 		test = gth_main_get_registered_object (GTH_TYPE_TEST, registered_test_id);
143 		data->general_tests = g_list_prepend (data->general_tests, g_strdup (gth_test_get_id (test)));
144 
145 		gtk_list_store_append (GTK_LIST_STORE (GET_WIDGET ("file_type_liststore")), &iter);
146 		gtk_list_store_set (GTK_LIST_STORE (GET_WIDGET ("file_type_liststore")), &iter,
147 				    0, gth_test_get_display_name (test),
148 				    -1);
149 
150 		g_object_unref (test);
151 	}
152 	data->general_tests = g_list_reverse (data->general_tests);
153 
154 	gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("file_type_combobox")), active_filter);
155 
156 	g_free (general_filter);
157 	_g_string_list_free (tests);
158 	g_object_unref (settings);
159 
160 	/* Set the signals handlers. */
161 
162 	g_signal_connect (G_OBJECT (data->dialog),
163 			  "destroy",
164 			  G_CALLBACK (destroy_cb),
165 			  data);
166 	g_signal_connect (gtk_dialog_get_widget_for_response (GTK_DIALOG (data->dialog), GTK_RESPONSE_OK),
167 			  "clicked",
168 			  G_CALLBACK (ok_clicked_cb),
169 			  data);
170 	g_signal_connect_swapped (gtk_dialog_get_widget_for_response (GTK_DIALOG (data->dialog), GTK_RESPONSE_CANCEL),
171 				  "clicked",
172 				  G_CALLBACK (gtk_widget_destroy),
173 				  G_OBJECT (data->dialog));
174 
175 	/* Run dialog. */
176 
177 	gtk_window_set_transient_for (GTK_WINDOW (data->dialog), GTK_WINDOW (browser));
178 	gtk_window_set_modal (GTK_WINDOW (data->dialog), FALSE);
179 	gtk_widget_show (data->dialog);
180 }
181