1 /* gtkam-save.c
2 *
3 * Copyright 2001,2002 Lutz Mueller <lutz@users.sf.net>
4 * Copyright 2003,2004,2005 Andrew Burton <adburton@users.sourceforge.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "config.h"
21 #include "gtkam-save.h"
22 #include "i18n.h"
23
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdlib.h>
27
28 #include <gtk/gtk.h>
29 #include <gtk/gtktogglebutton.h>
30 #include <gtk/gtkbutton.h>
31 #include <gtk/gtkhbox.h>
32 #include <gtk/gtkvbox.h>
33 #include <gtk/gtkframe.h>
34 #include <gtk/gtkentry.h>
35 #include <gtk/gtkwindow.h>
36 #include <gtk/gtkspinbutton.h>
37 #include <gtk/gtktooltips.h>
38 #include <gtk/gtkcheckbutton.h>
39 #include <gtk/gtklabel.h>
40
41 #include <gphoto2/gphoto2-setting.h>
42
43 #include "util.h"
44
45 #include "gtkam-cancel.h"
46 #include "gtkam-close.h"
47 #include "gtkam-error.h"
48 #include "gtkam-status.h"
49
50 typedef struct _GtkamSaveData GtkamSaveData;
51 struct _GtkamSaveData {
52 GtkamCamera *camera;
53 gchar *folder;
54 gchar *name;
55 };
56
57
58 struct _GtkamSavePrivate
59 {
60 GSList *data;
61 GString *filelist;
62
63 GtkToggleButton *toggle_preview, *toggle_normal, *toggle_raw,
64 *toggle_audio, *toggle_exif;
65 GtkToggleButton *toggle_filename_camera;
66 GtkEntry *program;
67
68 GtkWidget *spin_entry, *prefix_entry, *hbox_prefix;
69
70 gboolean quiet, err_shown;
71
72 GtkWidget *status;
73 GtkWindow *main_window;
74 };
75
76 #define PARENT_TYPE GTK_TYPE_FILE_CHOOSER_DIALOG
77 static GtkFileChooserDialog *parent_class;
78
79 static void
gtkam_save_destroy(GtkObject * object)80 gtkam_save_destroy (GtkObject *object)
81 {
82 GtkamSave *save = GTKAM_SAVE (object);
83 gint i;
84 GtkamSaveData *data;
85
86 if (save->priv->data) {
87 for (i = g_slist_length (save->priv->data) - 1; i >= 0; i--) {
88 data = g_slist_nth_data (save->priv->data, i);
89 g_object_unref (G_OBJECT (data->camera));
90 g_free (data->folder);
91 g_free (data->name);
92 g_free (data);
93 }
94 g_slist_free (save->priv->data);
95 save->priv->data = NULL;
96 }
97
98 GTK_OBJECT_CLASS (parent_class)->destroy (object);
99 }
100
101 static void
gtkam_save_finalize(GObject * object)102 gtkam_save_finalize (GObject *object)
103 {
104 GtkamSave *save = GTKAM_SAVE (object);
105
106 g_free (save->priv);
107
108 G_OBJECT_CLASS (parent_class)->finalize (object);
109 }
110
111 static void
gtkam_save_class_init(gpointer g_class,gpointer class_data)112 gtkam_save_class_init (gpointer g_class, gpointer class_data)
113 {
114 GtkObjectClass *object_class;
115 GObjectClass *gobject_class;
116
117 object_class = GTK_OBJECT_CLASS (g_class);
118 object_class->destroy = gtkam_save_destroy;
119
120 gobject_class = G_OBJECT_CLASS (g_class);
121 gobject_class->finalize = gtkam_save_finalize;
122
123 parent_class = g_type_class_peek_parent (g_class);
124 }
125
126 static void
gtkam_save_init(GTypeInstance * instance,gpointer g_class)127 gtkam_save_init (GTypeInstance *instance, gpointer g_class)
128 {
129 GtkamSave *save = GTKAM_SAVE (instance);
130
131 save->priv = g_new0 (GtkamSavePrivate, 1);
132 }
133
134 GType
gtkam_save_get_type(void)135 gtkam_save_get_type (void)
136 {
137 static GType type = 0;
138
139 if (!type) {
140 GTypeInfo ti;
141
142 memset (&ti, 0, sizeof (GTypeInfo));
143 ti.class_size = sizeof (GtkamSaveClass);
144 ti.class_init = gtkam_save_class_init;
145 ti.instance_size = sizeof (GtkamSave);
146 ti.instance_init = gtkam_save_init;
147
148 type = g_type_register_static (PARENT_TYPE, "GtkamSave",
149 &ti, 0);
150 }
151
152 return (type);
153 }
154
155 static void
on_cancel_clicked(GtkButton * button,GtkamSave * save)156 on_cancel_clicked (GtkButton *button, GtkamSave *save)
157 {
158 gtk_widget_destroy (GTK_WIDGET (save));
159 }
160
161 static int
default_numbering_start(const GtkamSave * save)162 default_numbering_start(const GtkamSave *save)
163 {
164 GDir *dir;
165 const gchar *file;
166 gchar *tail,*prefix;
167 int max = 1;
168 int plen, current;
169 gchar *filename ;
170
171 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (save));
172 if (filename == NULL) return 1;
173 if (!(dir = g_dir_open (filename , 0, NULL))) return 1;
174 prefix = g_strdup (gtk_entry_get_text
175 (GTK_ENTRY (save->priv->prefix_entry)));
176 plen = strlen (prefix);
177 while ((file = g_dir_read_name (dir))) {
178 /* compare prefix */
179 if (strncmp (prefix, file, plen)) continue;
180 /* check number */
181 current = strtol (file+plen, &tail, 10);
182 if (tail - (file + plen) != 4) continue;
183 /* FIXME: check for regular file here */
184 if (max <= current) max = current + 1;
185 }
186
187 g_free (prefix);
188 g_dir_close (dir);
189 return max;
190 }
191
192 static void
on_filename_camera_toggled(GtkToggleButton * toggle,GtkamSave * save)193 on_filename_camera_toggled (GtkToggleButton *toggle, GtkamSave *save)
194 {
195 /*
196 * Give the users the possibility to specify prefix and numbering.
197 * No direct entry of filename is allowed.
198 */
199 gtk_widget_show (save->priv->hbox_prefix);
200 gtk_widget_set_sensitive (GTK_WIDGET (save->priv->prefix_entry),
201 !toggle->active);
202 gtk_widget_set_sensitive (GTK_WIDGET (save->priv->spin_entry),
203 !toggle->active);
204 if (!toggle->active) {
205 /* Calculate default start number */
206 gtk_spin_button_set_value (
207 GTK_SPIN_BUTTON (save->priv->spin_entry),
208 default_numbering_start (save));
209 }
210 }
211
212 static gchar *
create_full_filename(const gchar * filename,CameraFileType type)213 create_full_filename (const gchar *filename, CameraFileType type)
214 {
215 gchar *full_filename;
216
217 switch (type) {
218 case GP_FILE_TYPE_PREVIEW:
219 full_filename = g_strdup_printf ("thumb_%s", filename);
220 break;
221 case GP_FILE_TYPE_RAW:
222 full_filename = g_strdup_printf ("raw_%s", filename);
223 break;
224 case GP_FILE_TYPE_AUDIO:
225 full_filename = g_strdup_printf ("audio_%s", filename);
226 break;
227 case GP_FILE_TYPE_EXIF:
228 full_filename = g_strdup_printf ("exif_%s", filename);
229 break;
230 default:
231 full_filename = g_strdup (filename);
232 break;
233 }
234
235 return (full_filename);
236 }
237
238 static gchar *
concat_dir_and_file(const gchar * dirname,const gchar * filename)239 concat_dir_and_file (const gchar *dirname, const gchar *filename)
240 {
241 gchar *full_path;
242
243 if (!strcmp (dirname, "/"))
244 full_path = g_strdup_printf ("/%s", filename);
245 else if (dirname[strlen (dirname) - 1] == '/')
246 full_path = g_strdup_printf ("%s%s", dirname, filename);
247 else
248 full_path = g_strdup_printf ("%s/%s", dirname, filename);
249 return (full_path);
250 }
251
252 static int
save_file(GtkamSave * save,const char * filename,CameraFile * file,CameraFileType type,guint n)253 save_file (GtkamSave *save, const char *filename, CameraFile *file, CameraFileType type, guint n)
254 {
255 gchar *full_path, *full_filename, *msg, *number_filename;
256 const char *mime_type;
257 const gchar *fsel_path, *prefix, *suffix;
258 GtkWidget *dialog;
259 int result;
260
261 gp_file_get_mime_type (file, &mime_type);
262
263 fsel_path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (save));
264
265 if ((save->priv->toggle_filename_camera->active) ||
266 (g_slist_length (save->priv->data) == 1)) {
267
268 /* Use filename provided by the CameraFile */
269 full_filename = create_full_filename (filename, type);
270
271 if (g_slist_length (save->priv->data) == 1)
272 full_path = g_strdup(fsel_path);
273 else
274 full_path = concat_dir_and_file (fsel_path, full_filename);
275
276 g_free (full_filename);
277
278 } else {
279 /* Use filename in prefix */
280 prefix = g_locale_from_utf8 (gtk_entry_get_text
281 (GTK_ENTRY (save->priv->prefix_entry)), -1,
282 NULL, NULL, NULL);
283
284 suffix = strrchr (mime_type, '/');
285 suffix++;
286 number_filename = g_strdup_printf ("%s%04i.%s", prefix,
287 n, suffix);
288 full_filename = create_full_filename (number_filename,
289 type);
290 g_free (number_filename);
291
292 full_path = concat_dir_and_file (fsel_path,
293 full_filename);
294 g_free (full_filename);
295 }
296
297 /* FIXME Check which is user, and prompt the user */
298 if (!save->priv->quiet && file_exists (full_path)) {
299 msg = g_strdup_printf (_("The file '%s' already exists."),
300 full_path);
301 if (!save->priv->err_shown) {
302 dialog = gtkam_error_new (GP_ERROR_FILE_EXISTS, NULL, GTK_WIDGET (save), msg);
303 gtk_window_set_transient_for (GTK_WINDOW (dialog),
304 save->priv->main_window);
305 gtk_widget_show (dialog);
306 g_free (msg);
307 g_free (full_path);
308 save->priv->err_shown = TRUE;
309 }
310 return -1;
311 }
312
313 /* FIXME Check for sufficient disk space for this file, or
314 calculate total disk space required for all files before
315 save process starts */
316
317 result = gp_file_save (file, full_path);
318 if (result < 0) {
319 if (!save->priv->err_shown) {
320 dialog = gtkam_error_new (result, NULL, GTK_WIDGET (save),
321 _("Could not save file to '%s'."), full_path);
322 gtk_widget_show (dialog);
323 save->priv->err_shown = TRUE;
324 }
325 } else {
326 /* Add the file to the list of files to be opened with
327 the specified external program */
328 if (!save->priv->filelist)
329 save->priv->filelist = g_string_new ("");
330 g_string_append_printf (save->priv->filelist, " %s", full_path);
331 }
332
333 g_free (full_path);
334
335 return result;
336 }
337
338 static int
get_file(GtkamSave * save,GtkamCamera * camera,const gchar * folder,const gchar * name,CameraFileType type,guint n,GtkamContext * context)339 get_file (GtkamSave *save, GtkamCamera *camera,
340 const gchar *folder, const gchar *name, CameraFileType type, guint n,
341 GtkamContext *context)
342 {
343 int result;
344 GtkWidget *dialog;
345 CameraFile *file;
346
347 gp_file_new (&file);
348 result = gp_camera_file_get (camera->camera, folder, name, type, file,
349 context->context);
350 if (camera->multi)
351 gp_camera_exit (camera->camera, NULL);
352 switch (result) {
353 case GP_OK:
354 result = save_file (save, name, file, type, n);
355 break;
356 case GP_ERROR_CANCEL:
357 break;
358 default:
359 if (!save->priv->err_shown) {
360 dialog = gtkam_error_new (result, context,
361 GTK_WIDGET (save), _("Could not get '%s' "
362 "from folder '%s'."),
363 name, folder);
364 gtk_widget_show (dialog);
365 save->priv->err_shown = TRUE;
366 }
367 }
368 gp_file_unref (file);
369
370 return result;
371 }
372
373 static void
store_save_settings(GtkamSave * save)374 store_save_settings(GtkamSave *save)
375 {
376 gchar *savedir,*t;
377 gchar buf[5];
378
379 /* Directory */
380 savedir = g_strdup (gtk_file_chooser_get_filename (
381 GTK_FILE_CHOOSER (save)));
382 if (savedir) {
383 if (strlen (savedir) > 255)
384 savedir[255] = '\0';
385
386 if (!g_file_test (savedir, G_FILE_TEST_IS_DIR)) {
387 t = g_path_get_dirname (savedir);
388 g_free (savedir);
389 savedir = t;
390 }
391 gp_setting_set ("gtkam", "save-dir", savedir);
392 g_free (savedir);
393 }
394
395 /* toggle buttons */
396 #define STORE_TOGGLE(NAME) \
397 snprintf(buf,sizeof(buf), "%d", gtk_toggle_button_get_active( \
398 save->priv->toggle_ ## NAME)); \
399 gp_setting_set("gtkam","save-" #NAME,buf)
400
401 STORE_TOGGLE(preview);
402 STORE_TOGGLE(normal);
403 STORE_TOGGLE(raw);
404 STORE_TOGGLE(audio);
405 STORE_TOGGLE(exif);
406 STORE_TOGGLE(filename_camera);
407
408 /* prefix entry */
409 if (g_slist_length (save->priv->data) > 1) {
410 /* only when saving several files */
411 gp_setting_set("gtkam", "save-prefix", (gchar *)
412 gtk_entry_get_text (GTK_ENTRY (save->priv->prefix_entry)));
413 }
414 }
415
416 static void
load_save_settings(GtkamSave * save)417 load_save_settings(GtkamSave *save)
418 {
419 gchar buf[1024];
420 gchar *dir;
421
422 /* directory */
423 if (gp_setting_get("gtkam","save-dir",buf) == GP_OK) {
424 dir = g_strdup (buf);
425 strcat (buf, G_DIR_SEPARATOR_S);
426 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (save), buf);
427 } else {
428 dir = g_strdup (gtk_file_chooser_get_filename (
429 GTK_FILE_CHOOSER (save)));
430 }
431 /* prefix entry */
432 gp_setting_get ("gtkam", "save-prefix", buf);
433 gtk_entry_set_text (GTK_ENTRY (save->priv->prefix_entry), buf);
434
435 /* toggle buttons */
436 #define LOAD_TOGGLE(NAME) \
437 gp_setting_get("gtkam","save-" #NAME,buf); \
438 gtk_toggle_button_set_active(save->priv->toggle_ ## NAME, atoi(buf))
439
440 LOAD_TOGGLE(preview);
441 LOAD_TOGGLE(normal);
442 LOAD_TOGGLE(raw);
443 LOAD_TOGGLE(audio);
444 LOAD_TOGGLE(exif);
445 LOAD_TOGGLE(filename_camera);
446 g_free(dir);
447 }
448
449 static int
count_items(GtkamSave * save)450 count_items (GtkamSave *save)
451 {
452 int items_to_save = 0;
453
454 if (save->priv->toggle_normal &&
455 save->priv->toggle_normal->active)
456 items_to_save++;
457
458 if (save->priv->toggle_preview &&
459 save->priv->toggle_preview->active)
460 items_to_save++;
461
462 if (save->priv->toggle_raw &&
463 save->priv->toggle_raw->active)
464 items_to_save++;
465
466 if (save->priv->toggle_audio &&
467 save->priv->toggle_audio->active)
468 items_to_save++;
469
470 if (save->priv->toggle_exif &&
471 save->priv->toggle_exif->active)
472 items_to_save++;
473
474 return items_to_save;
475 }
476
477 static void
on_ok_clicked(GtkButton * button,GtkamSave * save)478 on_ok_clicked (GtkButton *button, GtkamSave *save)
479 {
480 guint i, count, j = 1;
481 int result = -1;
482 GtkWidget *s, *dialog;
483 unsigned int id = 0;
484 GtkamSaveData *data;
485 gchar *command;
486 const gchar *progname;
487 GError *error = NULL;
488
489 if (count_items (save) == 0) {
490 if (!save->priv->err_shown) {
491
492 dialog = gtkam_error_new (result, NULL,
493 GTK_WIDGET (save), _("There is nothing to be saved."));
494 gtk_widget_show (dialog);
495 }
496
497 return;
498 }
499
500 store_save_settings(save);
501 gtk_widget_hide (GTK_WIDGET (save));
502
503 count = g_slist_length (save->priv->data);
504 if (count == 1)
505 s = gtkam_cancel_new (_("Downloading file"));
506 else
507 s = gtkam_cancel_new (_("Downloading %i files"), count);
508 gtk_window_set_transient_for (GTK_WINDOW (s), save->priv->main_window);
509 gtk_widget_show (s);
510
511 if (count > 1)
512 id = gp_context_progress_start (
513 GTKAM_CANCEL (s)->context->context, count,
514 _("Downloading %i files..."), count);
515
516 if (!save->priv->toggle_filename_camera->active)
517 j = gtk_spin_button_get_value_as_int (
518 GTK_SPIN_BUTTON (save->priv->spin_entry));
519
520 for (i = 0; i < count; i++) {
521 data = g_slist_nth_data (save->priv->data, i);
522
523 /* Check for shutdown */
524 if (!GTKAM_IS_SAVE (save))
525 return;
526
527 if (save->priv->toggle_normal &&
528 save->priv->toggle_normal->active)
529 result = get_file (save, data->camera,
530 data->folder, data->name,
531 GP_FILE_TYPE_NORMAL, i + j,
532 GTKAM_CANCEL (s)->context);
533 if (save->priv->toggle_preview &&
534 save->priv->toggle_preview->active &&
535 (!result < 0))
536 result = get_file (save, data->camera,
537 data->folder, data->name,
538 GP_FILE_TYPE_PREVIEW, i + j,
539 GTKAM_CANCEL (s)->context);
540 if (save->priv->toggle_raw &&
541 save->priv->toggle_raw->active &&
542 (!result < 0))
543 result = get_file (save, data->camera,
544 data->folder, data->name, GP_FILE_TYPE_RAW,
545 i + j, GTKAM_CANCEL (s)->context);
546 if (save->priv->toggle_audio &&
547 save->priv->toggle_audio->active &&
548 (!result < 0))
549 result = get_file (save, data->camera,
550 data->folder, data->name, GP_FILE_TYPE_AUDIO,
551 i + j, GTKAM_CANCEL (s)->context);
552 if (save->priv->toggle_exif &&
553 save->priv->toggle_exif->active &&
554 (!result < 0))
555 result = get_file (save, data->camera,
556 data->folder, data->name, GP_FILE_TYPE_EXIF,
557 i + j, GTKAM_CANCEL (s)->context);
558
559 if (result < 0)
560 {
561 if (count > 1)
562 gp_context_progress_stop (GTKAM_CANCEL (s)->context->context, id);
563 if (!save->priv->err_shown) {
564 dialog = gtkam_error_new (result, GTKAM_CANCEL (s)->context,
565 GTK_WIDGET (save), _("Problem getting '%s' "
566 "from folder '%s'."),
567 data->name, data->folder);
568 gtk_widget_show (dialog);
569 save->priv->err_shown = TRUE;
570 }
571
572 gtk_object_destroy (GTK_OBJECT (s));
573 gtk_object_destroy (GTK_OBJECT (save));
574 return;
575 }
576
577 if (count > 1)
578 gp_context_progress_update (
579 GTKAM_CANCEL (s)->context->context, id, i + 1);
580 gp_context_idle (GTKAM_CANCEL (s)->context->context);
581 if (gp_context_cancel (GTKAM_CANCEL (s)->context->context) ==
582 GP_CONTEXT_FEEDBACK_CANCEL)
583 break;
584 }
585 if (count > 1)
586 gp_context_progress_stop (
587 GTKAM_CANCEL (s)->context->context, id);
588
589 gtk_object_destroy (GTK_OBJECT (s));
590
591 /* If file(s) were saved and a program specified, load the program
592 passing the filenames */
593 if (result >= 0)
594 {
595 progname = gtk_entry_get_text (save->priv->program);
596
597 if (progname && progname[0] != '\0') {
598 command = g_strdup_printf ("%s%s", progname, save->priv->filelist->str);
599
600 /* FIXME Report any arising errors */
601 if (!g_spawn_command_line_async (command, &error)) {
602 g_warning ("Error running command\n");
603 g_error_free (error);
604 }
605
606 g_free (command);
607 g_string_free (save->priv->filelist, TRUE);
608 }
609 }
610
611 gtk_object_destroy (GTK_OBJECT (save));
612 }
613
614 GtkWidget *
gtkam_save_new(GtkWindow * main_window)615 gtkam_save_new (GtkWindow *main_window)
616 {
617 GtkamSave *save;
618 GtkWidget *hbox, *frame, *main_vbox, *check, *label, *entry, *button;
619 GtkObject *a;
620 GtkTooltips *tooltips;
621
622 save = g_object_new (GTKAM_TYPE_SAVE, NULL);
623
624 button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
625 gtk_widget_show (button);
626 g_signal_connect (GTK_OBJECT (button),
627 "clicked", GTK_SIGNAL_FUNC (on_cancel_clicked), save);
628 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (save)->action_area),
629 button);
630
631 button = gtk_button_new_from_stock (GTK_STOCK_OK);
632 gtk_widget_show (button);
633 g_signal_connect (GTK_OBJECT (button), "clicked",
634 GTK_SIGNAL_FUNC (on_ok_clicked), save);
635 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (save)->action_area),
636 button);
637
638 tooltips = gtk_tooltips_new ();
639
640 frame = gtk_frame_new (_("What to save:"));
641 gtk_widget_show (frame);
642 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (save), frame);
643
644 main_vbox = gtk_vbox_new (TRUE, 5);
645 gtk_widget_show (main_vbox);
646 gtk_container_add (GTK_CONTAINER (frame), main_vbox);
647
648 hbox = gtk_hbox_new (TRUE, 5);
649 gtk_widget_show (hbox);
650 gtk_container_add (GTK_CONTAINER (main_vbox), hbox);
651
652 check = gtk_check_button_new_with_label (_("Save photos"));
653 gtk_widget_show (check);
654 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
655 gtk_box_pack_start (GTK_BOX (hbox), check, TRUE, TRUE, 0);
656 gtk_tooltips_set_tip (tooltips, check, _("Photos will be saved if "
657 "this is checked"), NULL);
658 save->priv->toggle_normal = GTK_TOGGLE_BUTTON (check);
659
660 check = gtk_check_button_new_with_label (_("Save raw data"));
661 gtk_widget_show (check);
662 gtk_box_pack_start (GTK_BOX (hbox), check, TRUE, TRUE, 0);
663 gtk_tooltips_set_tip (tooltips, check, _("Raw data will be "
664 "saved if this is checked"), NULL);
665 save->priv->toggle_raw = GTK_TOGGLE_BUTTON (check);
666
667 check = gtk_check_button_new_with_label (_("Save audio data"));
668 gtk_widget_show (check);
669 gtk_box_pack_start (GTK_BOX (hbox), check, TRUE, TRUE, 0);
670 gtk_tooltips_set_tip (tooltips, check, _("Audio data will be "
671 "saved if this is checked"), NULL);
672 save->priv->toggle_audio = GTK_TOGGLE_BUTTON (check);
673
674 check = gtk_check_button_new_with_label (_("Save thumbnails"));
675 gtk_widget_show (check);
676 gtk_box_pack_start (GTK_BOX (hbox), check, TRUE, TRUE, 0);
677 gtk_tooltips_set_tip (tooltips, check, _("Thumbnails will be "
678 "saved if this is checked"), NULL);
679 save->priv->toggle_preview = GTK_TOGGLE_BUTTON (check);
680
681 check = gtk_check_button_new_with_label (_("Save EXIF data"));
682 gtk_widget_show (check);
683 gtk_box_pack_start (GTK_BOX (hbox), check, TRUE, TRUE, 0);
684 gtk_tooltips_set_tip (tooltips, check, _("EXIF data will be "
685 "saved if this is checked"), NULL);
686 save->priv->toggle_exif = GTK_TOGGLE_BUTTON (check);
687
688 hbox = gtk_hbox_new (FALSE, 0);
689 gtk_widget_show (hbox);
690 gtk_box_pack_start (GTK_BOX (main_vbox),
691 hbox, TRUE, TRUE, 0);
692
693 label = gtk_label_new (_("Open image(s) with: "));
694 gtk_widget_show (label);
695 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
696
697 entry = gtk_entry_new ();
698 gtk_widget_show (entry);
699 gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
700 gtk_tooltips_set_tip (tooltips, entry, _("Type in the name of the "
701 "program you want to run, leave blank "
702 "for none"), NULL);
703 save->priv->program = GTK_ENTRY (entry);
704
705 /* Filenames provided by camera */
706 check = gtk_check_button_new_with_label (_("Use filename(s) provided by the camera"));
707 gtk_widget_show (check);
708 gtk_box_pack_start (GTK_BOX (main_vbox),
709 check, TRUE, TRUE, 0);
710 gtk_tooltips_set_tip (tooltips, check, _("Choose whether to use the "
711 "filename provided by the camera"), NULL);
712 save->priv->toggle_filename_camera = GTK_TOGGLE_BUTTON (check);
713 gtk_toggle_button_set_active (save->priv->toggle_filename_camera, TRUE);
714 g_signal_connect (G_OBJECT (check), "toggled",
715 G_CALLBACK (on_filename_camera_toggled), save);
716
717 hbox = gtk_hbox_new (FALSE, 5);
718 gtk_widget_show (hbox);
719 gtk_box_pack_start (GTK_BOX (main_vbox),
720 hbox, TRUE, TRUE, 0);
721
722 save->priv->hbox_prefix = hbox;
723
724 label = gtk_label_new (_("Filename prefix: "));
725 gtk_widget_show (label);
726 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
727
728 save->priv->prefix_entry = gtk_entry_new ();
729 gtk_widget_show (save->priv->prefix_entry);
730 gtk_box_pack_start (GTK_BOX (hbox), save->priv->prefix_entry,
731 TRUE, TRUE, 0);
732
733 label = gtk_label_new (_("Start numbering with: "));
734 gtk_widget_show (label);
735 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
736
737 a = gtk_adjustment_new (1.0, 1.0, 10000.0, 1.0, 10.0, 10.0);
738 save->priv->spin_entry = gtk_spin_button_new (GTK_ADJUSTMENT (a),
739 1.0, 0);
740 gtk_widget_show (save->priv->spin_entry);
741 gtk_box_pack_start (GTK_BOX (hbox), save->priv->spin_entry,
742 FALSE, FALSE, 0);
743
744 load_save_settings(save);
745
746 /* Remember the main window (if given) */
747 save->priv->main_window = main_window ? main_window : GTK_WINDOW (save);
748
749 return (GTK_WIDGET (save));
750 }
751
752 void
gtkam_save_add(GtkamSave * save,GtkamCamera * camera,const gchar * folder,const gchar * name)753 gtkam_save_add (GtkamSave *save, GtkamCamera *camera,
754 const gchar *folder, const gchar *name)
755 {
756 GtkamSaveData *data;
757 gchar *title;
758
759 g_return_if_fail (GTKAM_IS_SAVE (save));
760 g_return_if_fail (GTKAM_IS_CAMERA (camera));
761 g_return_if_fail (folder != NULL);
762 g_return_if_fail (name != NULL);
763
764 data = g_new0 (GtkamSaveData, 1);
765 data->camera = camera;
766 g_object_ref (G_OBJECT (camera));
767 data->folder = g_strdup (folder);
768 data->name = g_strdup (name);
769 save->priv->data = g_slist_append (save->priv->data, data);
770
771 switch (g_slist_length (save->priv->data)) {
772 case 1:
773
774 /* First case: We have only one file. */
775 title = g_strdup_printf (_("Save '%s'..."), name);
776 gtk_window_set_title (GTK_WINDOW (save), title);
777 g_free (title);
778
779 gtk_widget_hide ( GTK_WIDGET(save->priv->toggle_filename_camera));
780
781 gtk_widget_hide (save->priv->hbox_prefix);
782 gtk_widget_set_sensitive (save->priv->spin_entry, FALSE);
783 gtk_widget_set_sensitive (save->priv->prefix_entry, FALSE);
784
785 gtk_file_chooser_set_action(GTK_FILE_CHOOSER (save),
786 GTK_FILE_CHOOSER_ACTION_SAVE);
787
788 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (save), name);
789
790 break;
791
792 default:
793
794 /* Second case: We have multiple files to save. */
795 gtk_window_set_title (GTK_WINDOW (save), _("Save photos..."));
796
797 gtk_widget_show (GTK_WIDGET (save->priv->toggle_filename_camera));
798
799 gtk_widget_show (save->priv->hbox_prefix);
800 gtk_widget_set_sensitive (save->priv->spin_entry,
801 !save->priv->toggle_filename_camera->active);
802 gtk_widget_set_sensitive (save->priv->prefix_entry,
803 !save->priv->toggle_filename_camera->active);
804 gtk_file_chooser_set_action(GTK_FILE_CHOOSER (save),
805 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
806
807 break;
808 }
809 }
810