67#ifdef GDK_WINDOWING_QUARTZ
71#include <glib/gstdio.h>
102 return _(
"File on disk");
106 const size_t old_params_size,
const int old_version,
const int new_version,
109 if(old_version == 1 && new_version == 3)
111 typedef struct dt_imageio_disk_v1_t
116 } dt_imageio_disk_v1_t;
119 dt_imageio_disk_v1_t *o = (dt_imageio_disk_v1_t *)old_params;
121 g_strlcpy(
n->filename, o->filename,
sizeof(
n->filename));
124 *new_size = self->params_size(self);
127 if(old_version == 2 && new_version == 3)
129 typedef struct dt_imageio_disk_v2_t
134 } dt_imageio_disk_v2_t;
137 dt_imageio_disk_v2_t *o = (dt_imageio_disk_v2_t *)old_params;
139 g_strlcpy(
n->filename, o->filename,
sizeof(
n->filename));
142 *new_size = self->params_size(self);
152 GtkFileChooserNative *filechooser = gtk_file_chooser_native_new(
153 _(
"select directory"), GTK_WINDOW(win), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
154 _(
"_select as output destination"), _(
"_cancel"));
156 gchar *old = g_strdup(gtk_entry_get_text(
d->entry));
157 char *c = g_strstr_len(old, -1,
"$");
159 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(filechooser), old);
161 if(gtk_native_dialog_run(GTK_NATIVE_DIALOG(filechooser)) == GTK_RESPONSE_ACCEPT)
163 gchar *dir = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(filechooser));
164 char *composed = g_build_filename(dir,
"$(FILE_NAME)", NULL);
171 gtk_entry_set_text(GTK_ENTRY(
d->entry), escaped);
172 gtk_editable_set_position(GTK_EDITABLE(
d->entry), strlen(escaped));
177 g_object_unref(filechooser);
182 dt_conf_set_string(
"plugins/imageio/storage/disk/file_directory", gtk_entry_get_text(entry));
198 gtk_box_pack_start(GTK_BOX(self->
widget), GTK_WIDGET(hbox),
TRUE,
FALSE, 0);
200 widget = gtk_entry_new();
202 gtk_box_pack_start(GTK_BOX(hbox), widget,
TRUE,
TRUE, 0);
206 gtk_entry_set_text(GTK_ENTRY(widget), dir);
207 gtk_editable_set_position(GTK_EDITABLE(widget), strlen(dir));
212 d->entry = GTK_ENTRY(widget);
213 gtk_entry_set_width_chars(GTK_ENTRY(widget), 0);
214 gtk_widget_set_tooltip_text(widget,
215 _(
"enter the path where to put exported images\nvariables support bash like string manipulation\n"
216 "type '$(' to activate the completion and see the list of variables"));
220 gtk_widget_set_tooltip_text(widget, _(
"select directory"));
221 gtk_box_pack_start(GTK_BOX(hbox), widget,
FALSE,
FALSE, 0);
222 g_signal_connect(G_OBJECT(widget),
"clicked", G_CALLBACK(
button_clicked), self);
226 gtk_widget_set_tooltip_text(
d->onsave_action, _(
"Expected behaviour if the current naming pattern\n"
227 "produces a filename that already exists."));
231 gtk_box_pack_start(GTK_BOX(self->
widget),
d->onsave_action,
TRUE,
TRUE, 0);
248 dt_conf_set_string(
"plugins/imageio/storage/disk/file_directory", gtk_entry_get_text(
d->entry));
254 const gboolean high_quality,
const gboolean export_masks,
263 g_strlcpy(pattern,
d->filename,
sizeof(pattern));
264 gboolean from_cache =
FALSE;
269 gboolean fail =
FALSE;
275 if(total > 1 && !g_strrstr(pattern,
"$"))
277 snprintf(pattern + strlen(pattern),
sizeof(pattern) - strlen(pattern),
"_$(SEQUENCE)");
281 g_strlcpy(pattern, fixed_path,
sizeof(pattern));
284 d->vp->filename = input_dir;
285 d->vp->jobcode =
"export";
286 d->vp->imgid = imgid;
287 d->vp->sequence = num;
290 g_strlcpy(filename, result_filename,
sizeof(filename));
295 char last_char = *(filename + strlen(filename) - 1);
296 if(last_char ==
'/' || last_char ==
'\\')
300 if (snprintf(pattern,
sizeof(pattern),
"%s" G_DIR_SEPARATOR_S
"$(FILE_NAME)",
d->filename) <
sizeof(pattern))
304 char *output_dir = g_path_get_dirname(filename);
306 if(g_mkdir_with_parents(output_dir, 0755))
308 fprintf(stderr,
"[imageio_storage_disk] could not create directory: `%s'!\n", output_dir);
309 dt_control_log(_(
"could not create directory `%s'!"), output_dir);
313 if(g_access(output_dir, W_OK | X_OK) != 0)
315 fprintf(stderr,
"[imageio_storage_disk] could not write to directory: `%s'!\n", output_dir);
316 dt_control_log(_(
"could not write to directory `%s'!"), output_dir);
321 const char *ext = format->extension(fdata);
322 char *c = filename + strlen(filename);
323 size_t filename_free_space =
sizeof(filename) - (c - filename);
324 snprintf(c, filename_free_space,
".%s", ext);
333 while(g_file_test(filename, G_FILE_TEST_EXISTS))
335 snprintf(c, filename_free_space,
"_%.2d.%s", seq, ext);
342 if(g_file_test(filename, G_FILE_TEST_EXISTS))
345 fprintf(stderr,
"[export_job] skipping `%s'\n", filename);
346 dt_control_log(ngettext(
"%d/%d skipping `%s'",
"%d/%d skipping `%s'", num),
347 num, total, filename);
357 icc_filename, icc_intent, self, sdata, num, total, metadata) != 0)
359 fprintf(stderr,
"[imageio_storage_disk] could not export to file: `%s'!\n", filename);
364 fprintf(stderr,
"[export_job] exported to `%s'\n", filename);
365 dt_control_log(ngettext(
"%d/%d exported to `%s'",
"%d/%d exported to `%s'", num),
366 num, total, filename);
384 g_strlcpy(
d->filename, text,
sizeof(
d->filename));
386 d->onsave_action =
dt_conf_get_int(
"plugins/imageio/storage/disk/overwrite");
407 if(
size != self->params_size(self))
return 1;
409 gtk_entry_set_text(GTK_ENTRY(
g->entry),
d->filename);
410 gtk_editable_set_position(GTK_EDITABLE(
g->entry), strlen(
d->filename));
420 return g_strdup(_(
"you are going to export on overwrite mode, this will overwrite any existing images\n\n"
421 "do you really want to continue?"));
int dt_bauhaus_combobox_get(GtkWidget *widget)
void dt_bauhaus_combobox_set(GtkWidget *widget, const int pos)
void dt_bauhaus_widget_set_label(GtkWidget *widget, const char *label)
GtkWidget * dt_bauhaus_combobox_new(dt_bauhaus_t *bh, dt_gui_module_t *self)
void dt_bauhaus_combobox_add(GtkWidget *widget, const char *text)
dt_colorspaces_color_profile_type_t
void dt_image_full_path(const int32_t imgid, char *pathname, size_t pathname_len, gboolean *from_cache, const char *calling_func)
Get the full path of an image out of the database.
int dt_conf_get_bool(const char *name)
void dt_conf_set_int(const char *name, int val)
int dt_conf_get_int(const char *name)
int dt_confgen_get_int(const char *name, dt_confgen_value_kind_t kind)
void dt_conf_set_string(const char *name, const char *val)
const char * dt_conf_get_string_const(const char *name)
const char * dt_confgen_get(const char *name, dt_confgen_value_kind_t kind)
void dt_control_log(const char *msg,...)
#define DT_MODULE(MODVER)
#define DT_MAX_PATH_FOR_PARAMS
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
void * get_params(dt_imageio_module_storage_t *self)
char * ask_user_confirmation(dt_imageio_module_storage_t *self)
void gui_cleanup(dt_imageio_module_storage_t *self)
void free_params(dt_imageio_module_storage_t *self, dt_imageio_module_data_t *params)
static void onsave_action_toggle_callback(GtkWidget *widget, gpointer user_data)
size_t params_size(dt_imageio_module_storage_t *self)
void gui_init(dt_imageio_module_storage_t *self)
void init(dt_imageio_module_storage_t *self)
void gui_reset(dt_imageio_module_storage_t *self)
dt_disk_onconflict_actions_t
@ DT_EXPORT_ONCONFLICT_SKIP
@ DT_EXPORT_ONCONFLICT_UNIQUEFILENAME
@ DT_EXPORT_ONCONFLICT_OVERWRITE
void * legacy_params(dt_imageio_module_storage_t *self, const void *const old_params, const size_t old_params_size, const int old_version, const int new_version, size_t *new_size)
int set_params(dt_imageio_module_storage_t *self, const void *params, const int size)
static void button_clicked(GtkWidget *widget, dt_imageio_module_storage_t *self)
static void entry_changed_callback(GtkEntry *entry, gpointer user_data)
int store(dt_imageio_module_storage_t *self, dt_imageio_module_data_t *sdata, const int32_t imgid, dt_imageio_module_format_t *format, dt_imageio_module_data_t *fdata, const int num, const int total, const gboolean high_quality, const gboolean export_masks, dt_colorspaces_color_profile_type_t icc_type, const gchar *icc_filename, dt_iop_color_intent_t icc_intent, dt_export_metadata_t *metadata)
void dtgtk_cairo_paint_directory(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
static int dt_pthread_mutex_unlock(dt_pthread_mutex_t *mutex) RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
static int dt_pthread_mutex_lock(dt_pthread_mutex_t *mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
void dt_accels_disconnect_on_text_input(GtkWidget *widget)
Disconnects accels when a text or search entry gets the focus, and reconnects them when it looses it....
GtkWidget * dt_ui_main_window(dt_ui_t *ui)
get the main window widget
#define DT_GUI_BOX_SPACING
void dt_gtkentry_setup_completion(GtkEntry *entry, const dt_gtkentry_completion_spec *compl_list, const char *trigger_char)
const dt_gtkentry_completion_spec * dt_gtkentry_get_default_path_compl_list()
int dt_imageio_export(const int32_t imgid, const char *filename, dt_imageio_module_format_t *format, dt_imageio_module_data_t *format_params, const gboolean high_quality, const gboolean copy_metadata, const gboolean export_masks, dt_colorspaces_color_profile_type_t icc_type, const gchar *icc_filename, dt_iop_color_intent_t icc_intent, dt_imageio_module_storage_t *storage, dt_imageio_module_data_t *storage_params, int num, int total, dt_export_metadata_t *metadata)
struct _GtkWidget GtkWidget
char * dt_variables_expand(dt_variables_params_t *params, gchar *source, gboolean iterate)
void dt_variables_params_destroy(dt_variables_params_t *params)
void dt_variables_set_max_width_height(dt_variables_params_t *params, int max_width, int max_height)
void dt_variables_params_init(dt_variables_params_t **params)
struct dt_gui_gtk_t * gui
dt_pthread_mutex_t plugin_threadsafe
struct dt_bauhaus_t * bauhaus
GtkWidget * onsave_action
dt_variables_params_t * vp
dt_disk_onconflict_actions_t onsave_action
char filename[DT_MAX_PATH_FOR_PARAMS]
GModule *GtkWidget * widget
gchar * dt_util_str_replace(const gchar *string, const gchar *pattern, const gchar *substitute)
gchar * dt_util_fix_path(const gchar *path)