int dt_film_open(const int32_t id) { sqlite3_stmt *stmt; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "SELECT id, folder FROM main.film_rolls WHERE id = ?1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, id); if(sqlite3_step(stmt) == SQLITE_ROW) { sqlite3_finalize(stmt); char datetime[20]; dt_gettime(datetime, sizeof(datetime)); DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "UPDATE main.film_rolls SET datetime_accessed = ?1 WHERE id = ?2", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, datetime, -1, SQLITE_STATIC); DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, id); sqlite3_step(stmt); } sqlite3_finalize(stmt); // TODO: prefetch to cache using image_open dt_film_set_query(id); dt_control_queue_redraw_center(); dt_view_manager_reset(darktable.view_manager); return 0; }
// FIXME: needs a rewrite int dt_film_open_recent(const int num) { sqlite3_stmt *stmt; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "SELECT id FROM main.film_rolls ORDER BY datetime_accessed DESC LIMIT ?1,1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, num); if(sqlite3_step(stmt) == SQLITE_ROW) { int id = sqlite3_column_int(stmt, 0); sqlite3_finalize(stmt); if(dt_film_open(id)) return 1; char datetime[20]; dt_gettime(datetime, sizeof(datetime)); DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "UPDATE main.film_rolls SET datetime_accessed = ?1 WHERE id = ?2", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, datetime, -1, SQLITE_STATIC); DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, id); sqlite3_step(stmt); } sqlite3_finalize(stmt); // dt_control_update_recent_films(); return 0; }
// FIXME: needs a rewrite int dt_film_open_recent(const int num) { sqlite3_stmt *stmt; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select id from film_rolls order by datetime_accessed desc limit ?1,1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, num); if(sqlite3_step(stmt) == SQLITE_ROW) { int id = sqlite3_column_int(stmt, 0); sqlite3_finalize(stmt); if(dt_film_open(id)) return 1; char datetime[20]; dt_gettime(datetime); DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "update film_rolls set datetime_accessed = ?1 where id = ?2", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, datetime, strlen(datetime), SQLITE_STATIC); DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, id); sqlite3_step(stmt); } sqlite3_finalize(stmt); // dt_control_update_recent_films(); return 0; }
int dt_film_open(const int32_t id) { sqlite3_stmt *stmt; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select id, folder from film_rolls where id = ?1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, id); if(sqlite3_step(stmt) == SQLITE_ROW) { sqlite3_finalize(stmt); char datetime[20]; dt_gettime(datetime); DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "update film_rolls set datetime_accessed = ?1 where id = ?2", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, datetime, strlen(datetime), SQLITE_STATIC); DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, id); sqlite3_step(stmt); } sqlite3_finalize(stmt); // TODO: prefetch to cache using image_open dt_film_set_query(id); dt_control_queue_redraw_center(); dt_view_manager_reset(darktable.view_manager); return 0; }
int dt_film_new(dt_film_t *film, const char *directory) { // Try open filmroll for folder if exists film->id = -1; int rc; sqlite3_stmt *stmt; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select id from film_rolls where folder = ?1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, directory, strlen(directory), SQLITE_STATIC); if(sqlite3_step(stmt) == SQLITE_ROW) film->id = sqlite3_column_int(stmt, 0); sqlite3_finalize(stmt); if(film->id <= 0) { // create a new filmroll sqlite3_stmt *stmt; char datetime[20]; dt_gettime(datetime); DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "insert into film_rolls (id, datetime_accessed, folder) " "values (null, ?1, ?2)", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, datetime, strlen(datetime), SQLITE_STATIC); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 2, directory, strlen(directory), SQLITE_STATIC); dt_pthread_mutex_lock(&darktable.db_insert); rc = sqlite3_step(stmt); if(rc != SQLITE_DONE) fprintf(stderr, "[film_new] failed to insert film roll! %s\n", sqlite3_errmsg(dt_database_get(darktable.db))); sqlite3_finalize(stmt); DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select id from film_rolls where folder=?1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, directory, strlen(directory), SQLITE_STATIC); if(sqlite3_step(stmt) == SQLITE_ROW) film->id = sqlite3_column_int(stmt, 0); sqlite3_finalize(stmt); dt_pthread_mutex_unlock(&darktable.db_insert); } if(film->id<=0) return 0; g_strlcpy(film->dirname,directory,sizeof(film->dirname)); film->last_loaded = 0; return film->id; }
/** open film with given id. */ int dt_film_open2 (dt_film_t *film) { /* check if we got a decent film id */ if(film->id<0) return 1; /* query database for id and folder */ sqlite3_stmt *stmt; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select id, folder from film_rolls where id = ?1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, film->id); if(sqlite3_step(stmt) == SQLITE_ROW) { /* fill out the film dirname */ sprintf (film->dirname,"%s",(gchar *)sqlite3_column_text (stmt, 1)); sqlite3_finalize (stmt); char datetime[20]; dt_gettime (datetime); DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "update film_rolls set datetime_accessed = ?1 where id = ?2", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, datetime, strlen(datetime), SQLITE_STATIC); DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, film->id); sqlite3_step (stmt); sqlite3_finalize (stmt); dt_film_set_query (film->id); dt_control_queue_redraw_center (); dt_view_manager_reset (darktable.view_manager); return 0; } else sqlite3_finalize (stmt); /* failure */ return 1; }
int dt_film_import(const char *dirname) { int rc; sqlite3_stmt *stmt; GError *error = NULL; /* initialize a film object*/ dt_film_t *film = (dt_film_t *)malloc(sizeof(dt_film_t)); dt_film_init(film); film->id = -1; /* lookup if film exists and reuse id */ DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "SELECT id FROM main.film_rolls WHERE folder = ?1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, dirname, -1, SQLITE_STATIC); if(sqlite3_step(stmt) == SQLITE_ROW) film->id = sqlite3_column_int(stmt, 0); sqlite3_finalize(stmt); /* if we didn't find an id, lets instantiate a new filmroll */ if(film->id <= 0) { char datetime[20]; dt_gettime(datetime, sizeof(datetime)); /* insert a new film roll into database */ DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "INSERT INTO main.film_rolls (id, datetime_accessed, folder) VALUES " "(NULL, ?1, ?2)", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, datetime, -1, SQLITE_STATIC); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 2, dirname, -1, SQLITE_STATIC); rc = sqlite3_step(stmt); if(rc != SQLITE_DONE) fprintf(stderr, "[film_import] failed to insert film roll! %s\n", sqlite3_errmsg(dt_database_get(darktable.db))); sqlite3_finalize(stmt); /* requery for filmroll and fetch new id */ DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "SELECT id FROM main.film_rolls WHERE folder=?1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, dirname, -1, SQLITE_STATIC); if(sqlite3_step(stmt) == SQLITE_ROW) film->id = sqlite3_column_int(stmt, 0); sqlite3_finalize(stmt); } /* bail out if we got troubles */ if(film->id <= 0) { // if the film is empty => remove it again. if(dt_film_is_empty(film->id)) { dt_film_remove(film->id); } dt_film_cleanup(film); free(film); return 0; } // when called without job system running the import will be done synchronously and destroy the film object int filmid = film->id; /* at last put import film job on queue */ film->last_loaded = 0; g_strlcpy(film->dirname, dirname, sizeof(film->dirname)); char *last = &film->dirname[strlen(film->dirname) - 1]; if(*last == '/' && last != film->dirname) *last = '\0'; // remove the closing /, unless it's also the start film->dir = g_dir_open(film->dirname, 0, &error); if(error) { fprintf(stderr, "[film_import] failed to open directory %s: %s\n", film->dirname, error->message); g_error_free(error); dt_film_cleanup(film); free(film); return 0; } dt_control_add_job(darktable.control, DT_JOB_QUEUE_USER_BG, dt_film_import1_create(film)); return filmid; }
int dt_film_import(const char *dirname) { int rc; sqlite3_stmt *stmt; /* initialize a film object*/ dt_film_t *film = (dt_film_t *)malloc(sizeof(dt_film_t)); dt_film_init(film); film->id = -1; /* lookup if film exists and reuse id */ DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select id from film_rolls where folder = ?1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, dirname, strlen(dirname), SQLITE_STATIC); if(sqlite3_step(stmt) == SQLITE_ROW) film->id = sqlite3_column_int(stmt, 0); sqlite3_finalize(stmt); /* if we didn't find a id, lets instansiate a new filmroll */ if(film->id <= 0) { char datetime[20]; dt_gettime(datetime); /* insert a new film roll into database */ DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "insert into film_rolls (id, datetime_accessed, folder) values " "(null, ?1, ?2)", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, datetime, strlen(datetime), SQLITE_STATIC); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 2, dirname, strlen(dirname), SQLITE_STATIC); rc = sqlite3_step(stmt); if(rc != SQLITE_DONE) fprintf(stderr, "[film_import] failed to insert film roll! %s\n", sqlite3_errmsg(dt_database_get(darktable.db))); sqlite3_finalize(stmt); /* requery for filmroll and fetch new id */ DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select id from film_rolls where folder=?1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, dirname, strlen(dirname), SQLITE_STATIC); if(sqlite3_step(stmt) == SQLITE_ROW) film->id = sqlite3_column_int(stmt, 0); sqlite3_finalize(stmt); } /* bail out if we got troubles */ if(film->id <= 0) { // if the film is empty => remove it again. if(dt_film_is_empty(film->id)) { dt_film_remove(film->id); } dt_film_cleanup(film); free(film); return 0; } /* at last put import film job on queue */ dt_job_t j; film->last_loaded = 0; g_strlcpy(film->dirname, dirname, sizeof(film->dirname)); film->dir = g_dir_open(film->dirname, 0, NULL); dt_film_import1_init(&j, film); dt_control_add_job(darktable.control, &j); return film->id; }
int main(int argc, char *argv[]) { #ifdef _WIN32 // on Windows we have a hard time showing stuff printed to stdout/stderr to the user. // because of that we write it to a log file. char datetime[20]; dt_gettime(datetime, sizeof(datetime)); // make sure to not redirect output when the output is already being redirected, either to a file or a pipe. int out_type = GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)); int err_type = GetFileType(GetStdHandle(STD_ERROR_HANDLE)); gboolean redirect_output = ((out_type != FILE_TYPE_DISK && out_type != FILE_TYPE_PIPE) && (err_type != FILE_TYPE_DISK && err_type != FILE_TYPE_PIPE)); for(int k = 1; k < argc; k++) { // For simple arguments do not redirect stdout if(!strcmp(argv[k], "--help") || !strcmp(argv[k], "-h") || !strcmp(argv[k], "/?") || !strcmp(argv[k], "--version")) { redirect_output = FALSE; break; } } if(redirect_output) { // something like C:\Users\username\AppData\Local\Microsoft\Windows\Temporary Internet Files\darktable\darktable-log.txt char *logdir = g_build_filename(g_get_user_cache_dir(), "darktable", NULL); char *logfile = g_build_filename(logdir, "darktable-log.txt", NULL); g_mkdir_with_parents(logdir, 0700); g_freopen(logfile, "a", stdout); dup2(fileno(stdout), fileno(stderr)); // We don't need the console window anymore, free it // This ensures that only darktable's main window will be visible FreeConsole(); g_free(logdir); g_free(logfile); // don't buffer stdout/stderr. we have basically two options: unbuffered or line buffered. // unbuffered keeps the order in which things are printed but concurrent threads printing can lead to intermangled output. ugly. // line buffered should keep lines together but in my tests the order of things no longer matches. ugly and potentially confusing. // thus we are doing the thing that is just ugly (in rare cases) but at least not confusing. setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); printf("========================================\n"); printf("version: %s\n", darktable_package_string); printf("start: %s\n", datetime); printf("\n"); } #endif if(dt_init(argc, argv, TRUE, TRUE, NULL)) exit(1); dt_gui_gtk_run(darktable.gui); #ifdef _WIN32 if(redirect_output) { dt_gettime(datetime, sizeof(datetime)); printf("\n"); printf("end: %s\n", datetime); printf("========================================\n"); printf("\n"); } #endif exit(0); }
static int dt_film_import_blocking(const char *dirname, const int blocking) { int rc; sqlite3_stmt *stmt; /* intialize a film object*/ dt_film_t *film = (dt_film_t *)malloc(sizeof(dt_film_t)); dt_film_init(film); film->id = -1; /* lookup if film exists and reuse id */ DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select id from film_rolls where folder = ?1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, dirname, strlen(dirname), SQLITE_STATIC); if(sqlite3_step(stmt) == SQLITE_ROW) film->id = sqlite3_column_int(stmt, 0); sqlite3_finalize(stmt); /* if we didnt find a id, lets instansiate a new filmroll */ if(film->id <= 0) { char datetime[20]; dt_gettime(datetime); #if 0 /* Should we use one for the whole app? */ GVolumeMonitor *gv_monitor; gv_monitor = g_volume_monitor_get (); GList *mounts; mounts = g_volume_monitor_get_mounts(gv_monitor); gchar *mount_name = NULL; if (mounts != NULL) { GFile *mount_gfile; GMount *filmroll_mount; GError *error = NULL; gchar *filmroll_path; GFile *gdirname = g_file_new_for_path(dirname); filmroll_mount = g_file_find_enclosing_mount(gdirname, NULL, &error); g_object_unref(gdirname); if (!error) /* We are considering that the only error is that there is no mount * because the filmroll added is in a local drive */ { filmroll_path = g_file_get_path((g_mount_get_default_location(filmroll_mount))); for (int i=0; i < g_list_length (mounts); i++) { gchar *p; mount_gfile = g_mount_get_default_location((GMount *)g_list_nth_data(mounts, i)); p = g_file_get_path(mount_gfile); if (g_strcmp0(p, filmroll_path)) { mount_name = g_mount_get_name(g_list_nth_data(mounts, i)); break; } g_free(p); g_object_unref (mount_gfile); } g_free (filmroll_path); } if (filmroll_mount != NULL) g_object_unref (filmroll_mount); /* We haven't found the device in the list of connected devices. Let's suppose it is local */ if (mount_name == NULL) mount_name = g_strdup("Local"); } else mount_name = g_strdup("Local"); #endif /* insert a new film roll into database */ DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), // "insert into film_rolls (id, datetime_accessed, folder, external_drive) values " // "(null, ?1, ?2, ?3)", -1, &stmt, NULL); "insert into film_rolls (id, datetime_accessed, folder) values " "(null, ?1, ?2)", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, datetime, strlen(datetime), SQLITE_STATIC); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 2, dirname, strlen(dirname), SQLITE_STATIC); // DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 3, mount_name, strlen(mount_name), // SQLITE_STATIC); rc = sqlite3_step(stmt); if(rc != SQLITE_DONE) fprintf(stderr, "[film_import] failed to insert film roll! %s\n", sqlite3_errmsg(dt_database_get(darktable.db))); sqlite3_finalize(stmt); // if (mount_name != NULL) g_free (mount_name); /* requery for filmroll and fetch new id */ DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select id from film_rolls where folder=?1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, dirname, strlen(dirname), SQLITE_STATIC); if(sqlite3_step(stmt) == SQLITE_ROW) film->id = sqlite3_column_int(stmt, 0); sqlite3_finalize(stmt); } /* bail out if we got troubles */ if(film->id <= 0) { dt_film_cleanup(film); free(film); return 0; } /* at last put import film job on queue */ dt_job_t j; film->last_loaded = 0; g_strlcpy(film->dirname, dirname, 512); film->dir = g_dir_open(film->dirname, 0, NULL); dt_film_import1_init(&j, film); dt_control_add_job(darktable.control, &j); return film->id; }