2
This file is part of darktable,
3
copyright (c) 2009--2010 johannes hanika.
5
darktable is free software: you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation, either version 3 of the License, or
8
(at your option) any later version.
10
darktable is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
GNU General Public License for more details.
15
You should have received a copy of the GNU General Public License
16
along with darktable. If not, see <http://www.gnu.org/licenses/>.
19
#include "common/darktable.h"
20
#include "common/image.h"
21
#include "common/image_cache.h"
22
#include "common/imageio_module.h"
23
#include "common/imageio.h"
24
#include "common/variables.h"
25
#include "control/control.h"
26
#include "control/conf.h"
28
#include "dtgtk/button.h"
29
#include "dtgtk/paint.h"
32
#include <glade/glade.h>
44
typedef struct dt_imageio_disk_t
47
dt_variables_params_t *vp;
55
return _("file on disk");
59
button_clicked (GtkWidget *widget, dt_imageio_module_storage_t *self)
61
disk_t *d = (disk_t *)self->gui_data;
62
GtkWidget *win = glade_xml_get_widget (darktable.gui->main_window, "main_window");
63
GtkWidget *filechooser = gtk_file_chooser_dialog_new (_("select directory"),
65
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
66
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
67
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
70
gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(filechooser), FALSE);
71
gchar *old = g_strdup(gtk_entry_get_text(d->entry));
72
char *c = g_strstr_len(old, -1, "$");
74
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(filechooser), old);
76
if (gtk_dialog_run (GTK_DIALOG (filechooser)) == GTK_RESPONSE_ACCEPT)
78
gchar *dir = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filechooser));
80
snprintf(composed, 1024, "%s/$(FILE_NAME)", dir);
81
gtk_entry_set_text(GTK_ENTRY(d->entry), composed);
82
dt_conf_set_string("plugins/imageio/storage/disk/file_directory", composed);
85
gtk_widget_destroy (filechooser);
89
gui_init (dt_imageio_module_storage_t *self)
91
disk_t *d = (disk_t *)malloc(sizeof(disk_t));
92
self->gui_data = (void *)d;
93
self->widget = gtk_hbox_new(FALSE, 5);
96
widget = gtk_entry_new();
97
gtk_box_pack_start(GTK_BOX(self->widget), widget, TRUE, TRUE, 0);
98
gchar *dir = dt_conf_get_string("plugins/imageio/storage/disk/file_directory");
101
gtk_entry_set_text(GTK_ENTRY(widget), dir);
104
d->entry = GTK_ENTRY(widget);
105
dt_gui_key_accel_block_on_focus (GTK_WIDGET (d->entry));
106
gtk_object_set(GTK_OBJECT(widget), "tooltip-text", _("enter the path where to put exported images:\n"
107
"$(ROLL_NAME) - roll of the input image\n"
108
"$(FILE_DIRECTORY) - directory of the input image\n"
109
"$(FILE_NAME) - basename of the input image\n"
110
"$(FILE_EXTENSION) - extension of the input image\n"
111
"$(SEQUENCE) - sequence number\n"
116
"$(MINUTE) - minute\n"
117
"$(SECOND) - second\n"
118
"$(EXIF_YEAR) - exif year\n"
119
"$(EXIF_MONTH) - exif month\n"
120
"$(EXIF_DAY) - exif day\n"
121
"$(EXIF_HOUR) - exif hour\n"
122
"$(EXIF_MINUTE) - exif minute\n"
123
"$(EXIF_SECOND) - exif second\n"
124
"$(PICTURES_FOLDER) - pictures folder\n"
125
"$(HOME_FOLDER) - home folder\n"
126
"$(DESKTOP_FOLDER) - desktop folder"
128
widget = dtgtk_button_new(dtgtk_cairo_paint_directory, 0);
129
gtk_widget_set_size_request(widget, 18, 18);
130
gtk_object_set(GTK_OBJECT(widget), "tooltip-text", _("select directory"), (char *)NULL);
131
gtk_box_pack_start(GTK_BOX(self->widget), widget, FALSE, FALSE, 0);
132
g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(button_clicked), self);
136
gui_cleanup (dt_imageio_module_storage_t *self)
138
free(self->gui_data);
142
gui_reset (dt_imageio_module_storage_t *self)
144
disk_t *d = (disk_t *)self->gui_data;
145
// global default can be annoying:
146
// gtk_entry_set_text(GTK_ENTRY(d->entry), "$(FILE_DIRECTORY)/darktable_exported/$(FILE_NAME)");
147
dt_conf_set_string("plugins/imageio/storage/disk/file_directory", gtk_entry_get_text(d->entry));
151
store (dt_imageio_module_data_t *sdata, const int imgid, dt_imageio_module_format_t *format, dt_imageio_module_data_t *fdata, const int num, const int total)
153
dt_image_t *img = dt_image_cache_get(imgid, 'r');
155
dt_imageio_disk_t *d = (dt_imageio_disk_t *)sdata;
157
char filename[1024]= {0};
158
char dirname[1024]= {0};
159
dt_image_full_path(img->id, dirname, 1024);
161
// we're potentially called in parallel. have sequence number synchronized:
162
dt_pthread_mutex_lock(&darktable.plugin_threadsafe);
165
// if filenamepattern is a directory just let att ${FILE_NAME} as default..
166
if ( g_file_test(d->filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR) || ((d->filename+strlen(d->filename))[0]=='/' || (d->filename+strlen(d->filename))[0]=='\\') )
167
snprintf (d->filename+strlen(d->filename), 1024-strlen(d->filename), "$(FILE_NAME)");
169
// avoid braindead export which is bound to overwrite at random:
170
if(total > 1 && !g_strrstr(d->filename, "$"))
172
snprintf(d->filename+strlen(d->filename), 1024-strlen(d->filename), "_$(SEQUENCE)");
176
d->vp->filename = dirname;
177
d->vp->jobcode = "export";
179
d->vp->sequence = num;
180
dt_variables_expand(d->vp, d->filename, TRUE);
181
strncpy(filename, dt_variables_get_result(d->vp), 1024);
182
strncpy(dirname, filename, 1024);
184
char *c = dirname + strlen(dirname);
185
for(; c>dirname && *c != '/'; c--);
186
if(*c == '/') *c = '\0';
187
if(g_mkdir_with_parents(dirname, 0755))
189
fprintf(stderr, "[imageio_storage_disk] could not create directory: `%s'!\n", dirname);
190
dt_control_log(_("could not create directory `%s'!"), dirname);
191
dt_image_cache_release(img, 'r');
196
c = filename + strlen(filename);
197
for(; c>filename && *c != '.' && *c != '/' ; c--);
198
if(c <= filename || *c=='/') c = filename + strlen(filename);
200
const char *ext = format->extension(fdata);
201
sprintf(c,".%s",ext);
203
/* prevent overwrite of files */
206
if (!fail && g_file_test (filename,G_FILE_TEST_EXISTS))
210
sprintf(c,"_%.2d.%s",seq,ext);
213
while (g_file_test (filename,G_FILE_TEST_EXISTS));
216
} // end of critical block
217
dt_pthread_mutex_unlock(&darktable.plugin_threadsafe);
220
/* export image to file */
221
dt_imageio_export(img, filename, format, fdata);
222
dt_image_cache_release(img, 'r');
224
printf("[export_job] exported to `%s'\n", filename);
225
char *trunc = filename + strlen(filename) - 32;
226
if(trunc < filename) trunc = filename;
227
dt_control_log(_("%d/%d exported to `%s%s'"), num, total, trunc != filename ? ".." : "", trunc);
232
get_params(dt_imageio_module_storage_t *self, int* size)
234
dt_imageio_disk_t *d = (dt_imageio_disk_t *)malloc(sizeof(dt_imageio_disk_t));
235
memset(d, 0, sizeof(dt_imageio_disk_t));
236
// have to return the size of the struct to store (i.e. without all the variable pointers at the end)
237
*size = sizeof(dt_imageio_disk_t) - sizeof(void *);
238
disk_t *g = (disk_t *)self->gui_data;
240
dt_variables_params_init(&d->vp);
241
const char *text = gtk_entry_get_text(GTK_ENTRY(g->entry));
242
strncpy(d->filename, text, 1024);
243
dt_conf_set_string("plugins/imageio/storage/disk/file_directory", d->filename);
248
free_params(dt_imageio_module_storage_t *self, void *params)
250
dt_imageio_disk_t *d = (dt_imageio_disk_t *)params;
251
dt_variables_params_destroy(d->vp);
256
set_params(dt_imageio_module_storage_t *self, void *params, int size)
258
if(size != sizeof(dt_imageio_disk_t) - sizeof(void *)) return 1;
259
dt_imageio_disk_t *d = (dt_imageio_disk_t *)params;
260
disk_t *g = (disk_t *)self->gui_data;
261
gtk_entry_set_text(GTK_ENTRY(g->entry), d->filename);
262
dt_conf_set_string("plugins/imageio/storage/disk/file_directory", d->filename);