66#ifdef GDK_WINDOWING_QUARTZ
85 g_dir_close(film->
dir);
99 " FROM main.film_rolls"
100 " WHERE id = ?1", -1, &stmt, NULL);
103 if(sqlite3_step(stmt) == SQLITE_ROW)
105 dt_conf_set_string(
"plugins/lighttable/collect/string0", (gchar *)sqlite3_column_text(stmt, 1));
107 sqlite3_finalize(stmt);
113 int32_t filmroll_id = -1;
117 "SELECT id FROM main.film_rolls WHERE folder LIKE ?1",
119 "SELECT id FROM main.film_rolls WHERE folder = ?1",
123 if(sqlite3_step(stmt) == SQLITE_ROW) filmroll_id = sqlite3_column_int(stmt, 0);
124 sqlite3_finalize(stmt);
134 " FROM main.film_rolls"
135 " WHERE id = ?1", -1, &stmt, NULL);
138 if(sqlite3_step(stmt) == SQLITE_ROW)
140 sqlite3_finalize(stmt);
144 "UPDATE main.film_rolls"
145 " SET access_timestamp = strftime('%s', 'now')"
146 " WHERE id = ?1", -1, &stmt,
152 sqlite3_finalize(stmt);
171 if(*last ==
'/' && last != film->
dirname) *last =
'\0';
183 "INSERT INTO main.film_rolls (id, access_timestamp, folder)"
184 " VALUES (NULL, strftime('%s', 'now'), ?1)",
188 const int rc = sqlite3_step(stmt);
189 if(rc != SQLITE_DONE)
190 fprintf(stderr,
"[film_new] failed to insert film roll! %s\n",
192 sqlite3_finalize(stmt);
201 "INSERT INTO memory.film_folder (id, status) "
207 sqlite3_finalize(stmt2);
216 "SELECT folder FROM main.film_rolls WHERE id = ?1",
220 if(sqlite3_step(stmt) != SQLITE_ROW)
221 g_strlcpy(film->
dirname, (
const char *)sqlite3_column_text(stmt, 0),
sizeof(film->
dirname));
222 sqlite3_finalize(stmt);
231 if(film->
id <= 0)
return 0;
238 GError *
error = NULL;
260 const int filmid = film->
id;
267 fprintf(stderr,
"[film_import] failed to open directory %s: %s\n", film->
dirname,
error->message);
282 GList *empty_dirs = (GList *)user_data;
283 const int n_empty_dirs = g_list_length(empty_dirs);
288 dialog = gtk_message_dialog_new(GTK_WINDOW(win), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION,
290 ngettext(
"do you want to remove this empty directory?",
291 "do you want to remove these empty directories?", n_empty_dirs));
292#ifdef GDK_WINDOWING_QUARTZ
296 gtk_window_set_title(GTK_WINDOW(dialog),
297 ngettext(
"remove empty directory?",
"remove empty directories?", n_empty_dirs));
299 GtkWidget *content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
301 GtkWidget *scroll = gtk_scrolled_window_new(NULL, NULL);
302 gtk_widget_set_vexpand(scroll,
TRUE);
305 GtkListStore *
store = gtk_list_store_new(1, G_TYPE_STRING);
307 for(GList *list_iter = empty_dirs; list_iter; list_iter = g_list_next(list_iter))
310 gtk_list_store_append(
store, &iter);
311 gtk_list_store_set(
store, &iter, 0, list_iter->data, -1);
314 GtkWidget *tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(
store));
315 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree),
FALSE);
316 gtk_widget_set_name(GTK_WIDGET(tree),
"delete-dialog");
317 GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes(_(
"name"), gtk_cell_renderer_text_new(),
319 gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
321 gtk_container_add(GTK_CONTAINER(scroll), tree);
322 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
323 gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(scroll),
DT_PIXEL_APPLY_DPI(25));
325 gtk_container_add(GTK_CONTAINER(content_area), scroll);
327 gtk_widget_show_all(dialog);
329 const gint res = gtk_dialog_run(GTK_DIALOG(dialog));
330 gtk_widget_destroy(dialog);
331 if(res == GTK_RESPONSE_YES)
332 for(GList *iter = empty_dirs; iter; iter = g_list_next(iter))
333 rmdir((
char *)iter->data);
337 g_object_unref(
store);
345 GList *empty_dirs = NULL;
347 gboolean raise_signal =
FALSE;
351 " FROM main.film_rolls AS B"
352 " WHERE (SELECT COUNT(*)"
353 " FROM main.images AS A"
354 " WHERE A.film_id=B.id) = 0",
356 while(sqlite3_step(stmt) == SQLITE_ROW)
358 sqlite3_stmt *inner_stmt;
360 const gint
id = sqlite3_column_int(stmt, 0);
361 const gchar *folder = (
const gchar *)sqlite3_column_text(stmt, 1);
363 "DELETE FROM main.film_rolls WHERE id=?1", -1,
366 sqlite3_step(inner_stmt);
367 sqlite3_finalize(inner_stmt);
371 if(ask_before_rmdir) empty_dirs = g_list_prepend(empty_dirs, g_strdup(folder));
375 sqlite3_finalize(stmt);
385 gboolean empty =
FALSE;
388 "SELECT id FROM main.images WHERE film_id = ?1", -1,
391 if(sqlite3_step(stmt) != SQLITE_ROW) empty =
TRUE;
392 sqlite3_finalize(stmt);
404 gboolean remove_ok =
TRUE;
407 "SELECT id FROM main.images WHERE film_id = ?1", -1,
411 while(sqlite3_step(stmt) == SQLITE_ROW)
413 const int32_t imgid = sqlite3_column_int(stmt, 0);
420 sqlite3_finalize(stmt);
424 dt_control_log(_(
"cannot remove film roll having local copies with non accessible originals"));
430 "SELECT id FROM main.images WHERE film_id = ?1", -1,
433 while(sqlite3_step(stmt) == SQLITE_ROW)
435 const int32_t imgid = sqlite3_column_int(stmt, 0);
440 sqlite3_finalize(stmt);
445 "DELETE FROM main.film_rolls WHERE id = ?1", -1,
449 sqlite3_finalize(stmt);
462 gchar *like = g_strdup_printf(
"%s%%", old_path);
464 "SELECT id, folder FROM main.film_rolls WHERE folder LIKE ?1", -1, &stmt, NULL);
469 GList *folders = NULL;
470 while(sqlite3_step(stmt) == SQLITE_ROW)
472 const int id = sqlite3_column_int(stmt, 0);
473 const gchar *old = (
const gchar *)sqlite3_column_text(stmt, 1);
474 gchar *
final = g_strcmp0(old, old_path) ? g_strdup_printf(
"%s/%s", new_path, old + strlen(old_path) + 1)
475 : g_strdup(new_path);
476 ids = g_list_prepend(ids, GINT_TO_POINTER(
id));
477 folders = g_list_prepend(folders,
final);
479 sqlite3_finalize(stmt);
483 "UPDATE main.film_rolls SET folder=?1 WHERE id=?2", -1, &up, NULL);
484 for(GList *
i = ids, *
f = folders;
i &&
f;
i = g_list_next(
i),
f = g_list_next(
f))
487 sqlite3_clear_bindings(up);
492 sqlite3_finalize(up);
494 g_list_free_full(folders, g_free);
499 GList *result = NULL;
502 "SELECT id FROM main.images WHERE film_id = ?1",
505 while(sqlite3_step(stmt) == SQLITE_ROW)
507 const int id = sqlite3_column_int(stmt, 0);
508 result = g_list_prepend(result, GINT_TO_POINTER(
id));
510 sqlite3_finalize(stmt);
511 return g_list_reverse(result);
516 sqlite3_stmt *stmt, *stmt2;
518 "DELETE FROM memory.film_folder",
521 sqlite3_finalize(stmt);
524 "SELECT id, folder FROM main.film_rolls",
529 "INSERT INTO memory.film_folder (id, status) "
534 while(sqlite3_step(stmt) == SQLITE_ROW)
536 const int filmid = sqlite3_column_int(stmt, 0);
537 const char *folder = (
char *)sqlite3_column_text(stmt, 1);
538 const int status = g_file_test(folder, G_FILE_TEST_IS_DIR);
542 sqlite3_reset(stmt2);
544 sqlite3_finalize(stmt);
545 sqlite3_finalize(stmt2);
static void error(char *msg)
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_aligned_pixel_t f
int dt_image_local_copy_reset(const int32_t imgid)
gboolean dt_image_safe_remove(const int32_t imgid)
int dt_conf_get_bool(const char *name)
void dt_conf_set_int(const char *name, int val)
void dt_conf_set_string(const char *name, const char *val)
void dt_control_log(const char *msg,...)
void dt_control_queue_redraw_center()
request redraw of center window. This redraws the center view within a gdk critical section to preven...
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...
sqlite3 * dt_database_get(const dt_database_t *db)
#define DT_DEBUG_SQLITE3_PREPARE_V2(a, b, c, d, e)
#define DT_DEBUG_SQLITE3_BIND_TEXT(a, b, c, d, e)
#define DT_DEBUG_SQLITE3_BIND_INT(a, b, c)
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)
static int dt_pthread_mutex_init(dt_pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)
static int dt_pthread_mutex_destroy(dt_pthread_mutex_t *mutex)
void dt_film_init(dt_film_t *film)
void dt_film_relocate(const char *old_path, const char *new_path)
gboolean dt_film_is_empty(const int id)
int dt_film_new(dt_film_t *film, const char *directory)
void dt_film_remove_empty()
void dt_film_remove(const int id)
int32_t dt_film_get_id(const char *folder)
void dt_film_set_query(const int32_t id)
GList * dt_film_get_image_ids(const int filmid)
int dt_film_open(const int32_t id)
static gboolean ask_and_delete(gpointer user_data)
void dt_film_set_folder_status()
int dt_film_import(const char *dirname)
void dt_film_cleanup(dt_film_t *film)
dt_job_t * dt_film_import1_create(dt_film_t *film)
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_PIXEL_APPLY_DPI(value)
void dt_image_cache_remove(dt_image_cache_t *cache, const int32_t imgid)
int dt_control_add_job(dt_control_t *control, dt_job_queue_t queue_id, _dt_job_t *job)
void dt_mipmap_cache_remove(dt_mipmap_cache_t *cache, const int32_t imgid, const gboolean flush_disk)
void dt_osx_disallow_fullscreen(GtkWidget *widget)
#define DT_DEBUG_CONTROL_SIGNAL_RAISE(ctlsig, signal,...)
@ DT_SIGNAL_FILMROLLS_CHANGED
This signal is raised when a filmroll is deleted/changed but not imported.
@ DT_SIGNAL_FILMROLLS_REMOVED
This signal is raised only when a filmroll is removed.
struct _GtkWidget GtkWidget
struct dt_gui_gtk_t * gui
struct dt_collection_t * collection
struct dt_mipmap_cache_t * mipmap_cache
const struct dt_database_t * db
struct dt_control_signal_t * signals
struct dt_image_cache_t * image_cache
struct dt_view_manager_t * view_manager
struct dt_control_t * control
dt_pthread_mutex_t images_mutex
gboolean dt_util_is_dir_empty(const char *dirname)
void dt_view_manager_reset(dt_view_manager_t *vm)