50 if(g_mkdir_with_parents(path, 0755) == -1)
52 fprintf(stderr,
"failed to create directory %s.\n", path);
53 dt_control_log(_(
"Impossible to create directory %s.\nThe target may be full or read-only.\n"), path);
78 params->filename = g_strdup(filename);
79 params->sequence = index;
80 params->jobcode = g_strdup(data->
jobcode);
94 gchar *dir = g_build_path(G_DIR_SEPARATOR_S, data->
base_folder, path, (
char *) NULL);
96 gchar *res = g_build_path(G_DIR_SEPARATOR_S, data->
target_dir, file, (
char *) NULL);
115 return !
IS_NULL_PTR(dest_file_path) && dest_file_path[0] && g_file_test(dest_file_path, G_FILE_TEST_EXISTS);
125gboolean
_copy_file(
const char *filename,
const char *dest_file_path)
127 GFile *in = g_file_new_for_path(filename);
128 GFile *
out = g_file_new_for_path(dest_file_path);
130 gboolean res = g_file_copy(in,
out, G_FILE_COPY_NONE, 0, 0, 0, NULL);
151 const int32_t filmid =
dt_film_new(&film, dirname);
172 char *ext = norm_dest_file +
safe_strlen(norm_dest_file);
173 while(*ext !=
'.' && ext > norm_dest_file) ext--;
177 g_snprintf(xmp_dest_name,
PATH_MAX,
"%s.xmp", norm_dest_file);
179 g_snprintf(xmp_dest_name,
PATH_MAX,
"%.*s_%.2d%s.xmp", (
int)name_len, norm_dest_file, counter, ext);
198 if(g_list_length(xmp_files) > 0)
200 for(GList *current_xmp = xmp_files; current_xmp; current_xmp = g_list_next(current_xmp))
202 char *xmp_source = g_strdup((
char*) current_xmp->data);
203 gchar xmp_dest_name[
PATH_MAX] = { 0 };
207 int success =
_copy_file(xmp_source, xmp_dest_name);
209 (success) ?
"succeeded" :
"failed");
210 if(success) xmp_cntr++;
214 g_list_free(xmp_files);
231 (success) ?
"succeeded" :
"failed");
236 return success ? 1 : 0;
260 dt_print(
DT_DEBUG_IMPORT,
"[Import] EXIF will be read for %s because the pattern needs it (performance penalty)\n", filename);
280 fprintf(stdout,
"[Import] Unable to create the target folder %s.\n", data->
target_dir);
285 fprintf(stdout,
"[Import] Not allowed to write in the %s folder.\n", data->
target_dir);
294 g_strlcpy(img_path_to_db, dest_file_path, pathname_len);
296 fprintf(stderr,
"[Import] Unable to copy the file %s to %s.\n", img_path_to_db, dest_file_path);
300 *discarded = g_list_prepend(*discarded, g_strdup(filename));
301 g_strlcpy(img_path_to_db, dest_file_path, pathname_len);
302 dt_print(
DT_DEBUG_IMPORT,
"[Import] File copy skipped, the target file %s already exists on the destination.\n", dest_file_path);
320 GError *
error = NULL;
321 GFile *gfile = g_file_new_for_path(filename);
322 GFileInfo *info = g_file_query_info(gfile,
323 G_FILE_ATTRIBUTE_STANDARD_NAME
","
324 G_FILE_ATTRIBUTE_TIME_MODIFIED,
325 G_FILE_QUERY_INFO_NONE, NULL, &
error);
326 const char *fn = g_file_info_get_name(info);
328 const time_t datetime = g_file_info_get_attribute_uint64(info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
331 const char *
id = g_strconcat(fn,
"-", dt_txt, NULL);
333 g_object_unref(info);
334 g_object_unref(gfile);
335 g_clear_error(&
error);
348 const char *filename = (
const char*) img->data;
350 gchar img_path_to_db[
PATH_MAX] = { 0 };
351 gboolean process_error =
FALSE;
356 process_error =
_import_copy_file(filename, index, data, img_path_to_db,
sizeof(img_path_to_db), discarded);
359 g_strlcpy(img_path_to_db, filename,
sizeof(img_path_to_db));
363 else if(img_path_to_db[0] == 0)
364 fprintf(stderr,
"[Import] Could not import file from disk: empty file path\n");
371 dt_control_log(_(
"Error importing file in collection: %s"), img_path_to_db);
372 fprintf(stderr,
"[Import] Error importing file in collection: %s", img_path_to_db);
388 gchar message[32] = { 0 };
389 double fraction = (
double)index / (
double)elements;
390 snprintf(message,
sizeof(message), ngettext(
"importing %i/%i image",
"importing %i/%i images", index), index, elements);
405 for(GList *img = g_list_first(data->
imgs); img; img = g_list_next(img))
432 fprintf(stderr,
"No image imported!\n\n");
435 else if(index == 1 && xmps == 1)
441 dt_control_log(ngettext(
"imported %d image",
"imported %d images", index), index);
442 fprintf(stdout,
"%d files imported in database.\n\n", index);
447 return index >= 1 ? 0 : 1;
477 GtkWidget *dialog = gtk_dialog_new_with_buttons(
"Message",
479 GTK_DIALOG_DESTROY_WITH_PARENT,
483 gtk_window_set_title(GTK_WINDOW(dialog), _(
"Some files have not been copied"));
487 GtkWidget *label = gtk_label_new(_(
"The following source files have not been copied "
488 "because similarly-named files already exist on the destination. "
489 "This may be because the files have already been imported "
490 "or the naming pattern leads to non-unique file names."));
491 gtk_label_set_line_wrap(GTK_LABEL(label),
TRUE);
494 GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);
495 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_AUTOMATIC,
496 GTK_POLICY_AUTOMATIC);
497 gtk_scrolled_window_set_propagate_natural_height(GTK_SCROLLED_WINDOW(scrolled_window),
TRUE);
500 GtkListStore *
store = gtk_list_store_new(1, G_TYPE_STRING);
502 for(GList *file = g_list_first(data->
discarded); file; file = g_list_next(file))
506 gtk_list_store_append(
store, &iter);
507 gtk_list_store_set(
store, &iter, 0, (
char *)file->data, -1);
513 GtkTreeViewColumn *col = gtk_tree_view_column_new();
514 gtk_tree_view_column_set_title(col, _(
"Origin path"));
515 GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
516 gtk_tree_view_column_pack_start(col, renderer,
TRUE);
517 gtk_tree_view_column_set_attributes(col, renderer,
"text", 0, NULL);
518 gtk_tree_view_append_column(GTK_TREE_VIEW(
view), col);
519 g_object_unref(
store);
523 gtk_box_pack_start(GTK_BOX(box), label,
TRUE,
TRUE, 0);
524 gtk_box_pack_start(GTK_BOX(box), scrolled_window,
TRUE,
TRUE, 0);
526 gtk_container_add(GTK_CONTAINER(scrolled_window),
view);
529 GtkWidget *content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
530 gtk_container_add(GTK_CONTAINER(content_area), box);
531 gtk_widget_show_all(dialog);
533#ifdef GDK_WINDOWING_QUARTZ
537 gtk_dialog_run(GTK_DIALOG(dialog));
538 gtk_widget_destroy(dialog);
591 params->index = NULL;
__DT_CLONE_TARGETS__ int process(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid)
static void error(char *msg)
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
void dt_collection_load_filmroll(dt_collection_t *collection, const int32_t imgid, gboolean open_single_image)
void dt_collection_update_query(const dt_collection_t *collection, dt_collection_change_t query_change, dt_collection_properties_t changed_property, GList *list)
@ DT_COLLECTION_PROP_UNDEF
@ DT_COLLECTION_CHANGE_NEW_QUERY
const dt_colormatrix_t dt_aligned_pixel_t out
int32_t dt_image_import(const int32_t film_id, const char *filename, gboolean raise_signals)
char * dt_image_get_text_path_from_path(const char *image_path)
void dt_image_init(dt_image_t *img)
GList * dt_image_find_xmps(const char *filename)
int dt_image_read_duplicates(const uint32_t id, const char *filename, const gboolean clear_selection)
char * dt_image_build_text_path_from_path(const char *image_path)
void dt_conf_set_int(const char *name, int val)
void dt_control_log(const char *msg,...)
void * dt_control_image_enumerator_alloc()
void dt_control_image_enumerator_cleanup(void *p)
uint32_t view(const dt_view_t *self)
void dt_print(dt_debug_thread_t thread, const char *msg,...)
static void dt_free_gpointer(gpointer ptr)
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
gboolean dt_datetime_unix_to_exif(char *exif, const size_t exif_size, const time_t *unix)
#define DT_DATETIME_EXIF_LENGTH
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)
int dt_exif_read(dt_image_t *img, const char *path)
int dt_film_new(dt_film_t *film, const char *directory)
void dt_gui_add_class(GtkWidget *widget, const gchar *class_name)
GtkWidget * dt_ui_main_window(dt_ui_t *ui)
get the main window widget
#define DT_GUI_BOX_SPACING
#define DT_PIXEL_APPLY_DPI(value)
int _import_copy_file(const char *const filename, const int index, dt_control_import_t *data, gchar *img_path_to_db, size_t pathname_len, GList **discarded)
copy a file to a destination path after checking if everything is allright.
static void * _control_import_alloc()
int _import_copy_xmp(const char *const filename, gchar *dest_file_path)
Attempt to find all sidecar XMP files along an image file and import (copy) it to destination.
gboolean _create_dir(const char *path)
Creates folders from path. Returns TRUE if success.
static void _control_import_job_cleanup(void *p)
gchar * dt_build_filename_from_pattern(const char *const filename, const int index, dt_image_t *img, dt_control_import_t *data)
Build a full path for a given image file, given a pattern.
gboolean _copy_file(const char *filename, const char *dest_file_path)
Just copy a file. Returns 1 if success.
void dt_import_duplicate_get_dest_name(char *xmp_dest_name, const char *dest_file_path, const int counter)
Gets the computed xmp file name with apropriate number for import copy. It computes a duplicate name ...
static int _discarded_files_popup(dt_control_image_enumerator_t *params)
int32_t _import_image(const GList *img, dt_control_import_t *data, const int index, GList **discarded, int *xmps)
process to copy (or not) and import an image to database.
static int32_t _control_import_job_run(dt_job_t *job)
void _refresh_progress_counter(dt_job_t *job, const int elements, const int index)
void dt_control_import(dt_control_import_t data)
Process a list of images to import with or without copying the files on an arbitrary hard-drive.
static dt_job_t * _control_import_job_create(dt_control_import_t data)
gboolean _file_exist(const char *dest_file_path)
Tests if file exist. Returns 1 if so.
const int32_t _import_job(dt_control_import_t *data, gchar *img_path_to_db)
Add an image entry in the database and returns its imgID.
void _write_xmp_id(const char *filename, int32_t imgid)
gchar * _path_cleanup(gchar *path_in)
Replaces separator depending of the current OS and removes whitespaces.
int _import_copy_txt(const char *const filename, const char *dest_file_path)
void dt_control_import_data_free(dt_control_import_t *data)
dt_job_t * dt_control_job_create(dt_job_execute_callback execute, const char *msg,...)
int dt_control_add_job(dt_control_t *control, dt_job_queue_t queue_id, _dt_job_t *job)
void * dt_control_job_get_params(const _dt_job_t *job)
void dt_control_job_set_progress(dt_job_t *job, double value)
void dt_control_job_add_progress(dt_job_t *job, const char *message, gboolean cancellable)
void dt_control_job_set_progress_message(dt_job_t *job, const char *message)
void dt_control_job_set_params(_dt_job_t *job, void *params, dt_job_destroy_callback callback)
void dt_control_job_dispose(_dt_job_t *job)
void dt_osx_disallow_fullscreen(GtkWidget *widget)
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_params_init(dt_variables_params_t **params)
void dt_variables_set_datetime(dt_variables_params_t *params, GDateTime *datetime)
struct dt_gui_gtk_t * gui
struct dt_collection_t * collection
struct dt_control_t * control
char * target_file_pattern
char * target_subfolder_pattern
typedef double((*spd)(unsigned long int wavelength, double TempK))
gchar * dt_cleanup_separators(gchar *string)
gboolean dt_util_dir_exist(const char *dir)
gchar * dt_util_path_get_dirname(const gchar *filename)
gchar * dt_util_normalize_path(const gchar *_input)
size_t safe_strlen(const char *str)
check if the string is empty or NULL before calling strlen()
gboolean dt_util_test_writable_dir(const char *path)
gchar * dt_util_remove_whitespace(const gchar *path)