1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
3 /*
4 * GThumb
5 *
6 * Copyright (C) 2001-2010 The 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-change-date.h"
26 #include "gth-change-date-task.h"
27 #include "preferences.h"
28
29
30 #define GET_WIDGET(x) (_gtk_builder_get_widget (data->builder, (x)))
31 #define IS_ACTIVE(x) (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (x)))
32 #define HOURS_TO_SECONDS(h) ((h) * 3600)
33 #define MINS_TO_SECONDS(h) ((h) * 60)
34
35
36 typedef struct {
37 GthBrowser *browser;
38 GtkBuilder *builder;
39 GSettings *settings;
40 GtkWidget *dialog;
41 GtkWidget *date_selector;
42 GList *file_list;
43 } DialogData;
44
45
46 static void
dialog_destroy_cb(GtkWidget * widget,DialogData * data)47 dialog_destroy_cb (GtkWidget *widget,
48 DialogData *data)
49 {
50 _g_object_list_unref (data->file_list);
51 g_object_unref (data->settings);
52 g_object_unref (data->builder);
53 g_free (data);
54 }
55
56
57 static void
ok_button_clicked(GtkWidget * button,DialogData * data)58 ok_button_clicked (GtkWidget *button,
59 DialogData *data)
60 {
61 GthChangeFields change_fields;
62 GthChangeType change_type;
63 GthDateTime *date_time;
64 int time_adjustment;
65 GthTask *task;
66
67 date_time = NULL;
68
69 change_fields = 0;
70 if (IS_ACTIVE (GET_WIDGET ("change_last_modified_checkbutton")))
71 change_fields |= GTH_CHANGE_LAST_MODIFIED_DATE;
72 if (IS_ACTIVE (GET_WIDGET ("change_comment_checkbutton")))
73 change_fields |= GTH_CHANGE_COMMENT_DATE;
74
75 change_type = 0;
76 time_adjustment = 0;
77 if (IS_ACTIVE (GET_WIDGET ("to_following_date_radiobutton"))) {
78 change_type = GTH_CHANGE_TO_FOLLOWING_DATE;
79 date_time = gth_datetime_new ();
80 gth_time_selector_get_value (GTH_TIME_SELECTOR (data->date_selector), date_time);
81 }
82 else if (IS_ACTIVE (GET_WIDGET ("to_last_modified_date_radiobutton")))
83 change_type = GTH_CHANGE_TO_FILE_MODIFIED_DATE;
84 else if (IS_ACTIVE (GET_WIDGET ("to_creation_date_radiobutton")))
85 change_type = GTH_CHANGE_TO_FILE_CREATION_DATE;
86 else if (IS_ACTIVE (GET_WIDGET ("to_photo_original_date_radiobutton")))
87 change_type = GTH_CHANGE_TO_PHOTO_ORIGINAL_DATE;
88 else if (IS_ACTIVE (GET_WIDGET ("adjust_time_radiobutton"))) {
89 change_type = GTH_CHANGE_ADJUST_TIME;
90 time_adjustment = (HOURS_TO_SECONDS (gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (GET_WIDGET ("adjust_time_h_spinbutton"))))
91 + MINS_TO_SECONDS (gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (GET_WIDGET ("adjust_time_m_spinbutton"))))
92 + gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (GET_WIDGET ("adjust_time_s_spinbutton"))));
93 if (gtk_combo_box_get_active (GTK_COMBO_BOX (GET_WIDGET ("adjust_sign_combobox"))) == 1)
94 time_adjustment = -time_adjustment;
95 }
96
97 /* save the preferences */
98
99 g_settings_set_boolean (data->settings, PREF_CHANGE_DATE_SET_LAST_MODIFIED_DATE, (change_fields & GTH_CHANGE_LAST_MODIFIED_DATE) == GTH_CHANGE_LAST_MODIFIED_DATE);
100 g_settings_set_boolean (data->settings, PREF_CHANGE_DATE_SET_COMMENT_DATE, (change_fields & GTH_CHANGE_COMMENT_DATE) == GTH_CHANGE_COMMENT_DATE);
101
102 g_settings_set_boolean (data->settings, PREF_CHANGE_DATE_TO_FOLLOWING_DATE, change_type == GTH_CHANGE_TO_FOLLOWING_DATE);
103 if (change_type == GTH_CHANGE_TO_FOLLOWING_DATE) {
104 char *s;
105 s = gth_datetime_to_exif_date (date_time);
106 g_settings_set_string (data->settings, PREF_CHANGE_DATE_DATE, s);
107 g_free (s);
108 }
109 g_settings_set_boolean (data->settings, PREF_CHANGE_DATE_TO_FILE_MODIFIED_DATE, change_type == GTH_CHANGE_TO_FILE_MODIFIED_DATE);
110 g_settings_set_boolean (data->settings, PREF_CHANGE_DATE_TO_FILE_CREATION_DATE, change_type == GTH_CHANGE_TO_FILE_CREATION_DATE);
111 g_settings_set_boolean (data->settings, PREF_CHANGE_DATE_TO_PHOTO_ORIGINAL_DATE, change_type == GTH_CHANGE_TO_PHOTO_ORIGINAL_DATE);
112 g_settings_set_boolean (data->settings, PREF_CHANGE_DATE_ADJUST_TIME, change_type == GTH_CHANGE_ADJUST_TIME);
113 if (change_type == GTH_CHANGE_ADJUST_TIME)
114 g_settings_set_int (data->settings, PREF_CHANGE_DATE_TIME_ADJUSTMENT, time_adjustment);
115
116 /* exec the task */
117
118 task = gth_change_date_task_new (gth_browser_get_location (data->browser),
119 data->file_list,
120 change_fields,
121 change_type,
122 date_time,
123 time_adjustment);
124 gth_browser_exec_task (data->browser, task, GTH_TASK_FLAGS_DEFAULT);
125 gtk_widget_destroy (data->dialog);
126
127 g_object_unref (task);
128 gth_datetime_free (date_time);
129 }
130
131
132 static void
update_sensitivity(DialogData * data)133 update_sensitivity (DialogData *data)
134 {
135 gtk_dialog_set_response_sensitive (GTK_DIALOG (data->dialog),
136 GTK_RESPONSE_OK,
137 (IS_ACTIVE (GET_WIDGET ("change_last_modified_checkbutton"))
138 || IS_ACTIVE (GET_WIDGET ("change_comment_checkbutton"))));
139 gtk_widget_set_sensitive (data->date_selector, IS_ACTIVE (GET_WIDGET ("to_following_date_radiobutton")));
140 gtk_widget_set_sensitive (GET_WIDGET ("time_box"), IS_ACTIVE (GET_WIDGET ("adjust_time_radiobutton")));
141
142 if (IS_ACTIVE (GET_WIDGET ("change_last_modified_checkbutton"))) {
143 gtk_widget_set_sensitive (GET_WIDGET ("to_last_modified_date_radiobutton"), FALSE);
144 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("to_last_modified_date_radiobutton"))))
145 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("to_following_date_radiobutton")), TRUE);
146 }
147 else
148 gtk_widget_set_sensitive (GET_WIDGET ("to_last_modified_date_radiobutton"), TRUE);
149 }
150
151
152 static void
radio_button_clicked(GtkWidget * button,DialogData * data)153 radio_button_clicked (GtkWidget *button,
154 DialogData *data)
155 {
156 update_sensitivity (data);
157 }
158
159
160 void
dlg_change_date(GthBrowser * browser,GList * file_list)161 dlg_change_date (GthBrowser *browser,
162 GList *file_list)
163 {
164 DialogData *data;
165 GTimeVal timeval;
166 GthDateTime *datetime;
167
168 data = g_new0 (DialogData, 1);
169 data->browser = browser;
170 data->file_list = _g_object_list_ref (file_list);
171 data->builder = _gtk_builder_new_from_file ("change-date.ui", "change_date");
172 data->settings = g_settings_new (GTHUMB_CHANGE_DATE_SCHEMA);
173
174 /* Get the widgets. */
175
176 data->dialog = g_object_new (GTK_TYPE_DIALOG,
177 "title", _("Change Date"),
178 "transient-for", GTK_WINDOW (browser),
179 "modal", FALSE,
180 "destroy-with-parent", FALSE,
181 "use-header-bar", _gtk_settings_get_dialogs_use_header (),
182 NULL);
183 gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (data->dialog))),
184 _gtk_builder_get_widget (data->builder, "dialog_content"));
185 gtk_dialog_add_buttons (GTK_DIALOG (data->dialog),
186 _GTK_LABEL_CANCEL, GTK_RESPONSE_CANCEL,
187 _GTK_LABEL_EXECUTE, GTK_RESPONSE_OK,
188 NULL);
189 _gtk_dialog_add_class_to_response (GTK_DIALOG (data->dialog), GTK_RESPONSE_OK, GTK_STYLE_CLASS_SUGGESTED_ACTION);
190
191 data->date_selector = gth_time_selector_new ();
192 gth_time_selector_show_time (GTH_TIME_SELECTOR (data->date_selector), TRUE, TRUE);
193 gtk_widget_show (data->date_selector);
194 gtk_box_pack_start (GTK_BOX (GET_WIDGET ("date_selector_box")), data->date_selector, TRUE, TRUE, 0);
195
196 /* Set widgets data. */
197
198 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("change_last_modified_checkbutton")),
199 g_settings_get_boolean (data->settings, PREF_CHANGE_DATE_SET_LAST_MODIFIED_DATE));
200 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("change_comment_checkbutton")),
201 g_settings_get_boolean (data->settings, PREF_CHANGE_DATE_SET_COMMENT_DATE));
202
203 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("to_following_date_radiobutton")),
204 g_settings_get_boolean (data->settings, PREF_CHANGE_DATE_TO_FOLLOWING_DATE));
205
206 datetime = gth_datetime_new ();
207 g_get_current_time (&timeval);
208 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("to_following_date_radiobutton")))) {
209 char *s;
210 s = g_settings_get_string (data->settings, PREF_CHANGE_DATE_DATE);
211 if (strcmp (s, "") != 0)
212 gth_datetime_from_exif_date (datetime, s);
213 else
214 gth_datetime_from_timeval (datetime, &timeval);
215 g_free (s);
216 }
217 else
218 gth_datetime_from_timeval (datetime, &timeval);
219 gth_time_selector_set_value (GTH_TIME_SELECTOR (data->date_selector), datetime);
220 gth_datetime_free (datetime);
221
222 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("to_last_modified_date_radiobutton")),
223 g_settings_get_boolean (data->settings, PREF_CHANGE_DATE_TO_FILE_MODIFIED_DATE));
224 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("to_creation_date_radiobutton")),
225 g_settings_get_boolean (data->settings, PREF_CHANGE_DATE_TO_FILE_CREATION_DATE));
226 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("to_photo_original_date_radiobutton")),
227 g_settings_get_boolean (data->settings, PREF_CHANGE_DATE_TO_PHOTO_ORIGINAL_DATE));
228 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("adjust_time_radiobutton")),
229 g_settings_get_boolean (data->settings, PREF_CHANGE_DATE_ADJUST_TIME));
230 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("adjust_time_radiobutton")))) {
231 int adjustement;
232 int sign;
233 int hours;
234 int minutes;
235 int seconds;
236
237 adjustement = g_settings_get_int (data->settings, PREF_CHANGE_DATE_TIME_ADJUSTMENT);
238 if (adjustement < 0) {
239 sign = -1;
240 adjustement = - adjustement;
241 }
242 else
243 sign = 1;
244
245 hours = adjustement / 3600;
246 adjustement = adjustement % 3600;
247
248 minutes = adjustement / 60;
249 adjustement = adjustement % 60;
250
251 seconds = adjustement;
252
253 gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("adjust_time_h_spinbutton")), hours);
254 gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("adjust_time_m_spinbutton")), minutes);
255 gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("adjust_time_s_spinbutton")), seconds);
256 gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("adjust_sign_combobox")), (sign >= 0) ? 0 : 1);
257 }
258
259 update_sensitivity (data);
260
261 /* Set the signals handlers. */
262
263 g_signal_connect (G_OBJECT (data->dialog),
264 "destroy",
265 G_CALLBACK (dialog_destroy_cb),
266 data);
267 g_signal_connect_swapped (gtk_dialog_get_widget_for_response (GTK_DIALOG (data->dialog), GTK_RESPONSE_CANCEL),
268 "clicked",
269 G_CALLBACK (gtk_widget_destroy),
270 G_OBJECT (data->dialog));
271 g_signal_connect (gtk_dialog_get_widget_for_response (GTK_DIALOG (data->dialog), GTK_RESPONSE_OK),
272 "clicked",
273 G_CALLBACK (ok_button_clicked),
274 data);
275 g_signal_connect (GET_WIDGET ("change_last_modified_checkbutton"),
276 "clicked",
277 G_CALLBACK (radio_button_clicked),
278 data);
279 g_signal_connect (GET_WIDGET ("change_comment_checkbutton"),
280 "clicked",
281 G_CALLBACK (radio_button_clicked),
282 data);
283 g_signal_connect (GET_WIDGET ("to_following_date_radiobutton"),
284 "clicked",
285 G_CALLBACK (radio_button_clicked),
286 data);
287 g_signal_connect (GET_WIDGET ("to_last_modified_date_radiobutton"),
288 "clicked",
289 G_CALLBACK (radio_button_clicked),
290 data);
291 g_signal_connect (GET_WIDGET ("to_creation_date_radiobutton"),
292 "clicked",
293 G_CALLBACK (radio_button_clicked),
294 data);
295 g_signal_connect (GET_WIDGET ("to_photo_original_date_radiobutton"),
296 "clicked",
297 G_CALLBACK (radio_button_clicked),
298 data);
299 g_signal_connect (GET_WIDGET ("adjust_time_radiobutton"),
300 "clicked",
301 G_CALLBACK (radio_button_clicked),
302 data);
303
304 /* run dialog. */
305
306 gtk_widget_show (data->dialog);
307 }
308