100#define SELECT_QUERY "SELECT DISTINCT * FROM %s"
101#define LIMIT_QUERY "LIMIT ?1, ?2"
159 return &collection->
params;
167#define and_operator_initial() (0)
184#define or_operator_initial() (0)
218 "DELETE FROM memory.collected_images",
222 "DELETE FROM memory.sqlite_sequence"
223 " WHERE name='collected_images'",
228 gchar *ins_query = g_strdup_printf(
"INSERT INTO memory.collected_images (imgid) %s", query);
234 sqlite3_finalize(stmt);
249 const uint32_t tagid = collection->
tagid;
250 char tag[16] = { 0 };
251 snprintf(tag,
sizeof(tag),
"%u", tagid);
255 "SELECT DISTINCT mi.id FROM (SELECT"
256 " id, group_id, film_id, filename, datetime_taken, "
257 " flags, version, aspect_ratio,"
258 " maker, model, lens, aperture, exposure, focal_length,"
259 " iso, import_timestamp, change_timestamp,"
260 " export_timestamp, print_timestamp"
261 " FROM main.images AS mi %s%s WHERE ",
262 tagid ?
" LEFT JOIN main.tagged_images AS ti"
263 " ON ti.imgid = mi.id AND ti.tagid = " :
"",
271 gchar *wq, *sq, *selq_pre, *selq_post, *query;
272 wq = sq = selq_pre = selq_post = query = NULL;
278 wq = g_strdup(where_ext);
289 gboolean got_rating_filter
295 if(got_rating_filter)
334 if(got_rating_filter)
337 gboolean got_altered_filter
340 if(got_altered_filter)
352 wq =
dt_util_dstrcat(wq,
" %s id NOT IN (SELECT imgid FROM main.history) ",
356 if(got_altered_filter)
363 wq =
dt_util_dstrcat(wq,
" %s id IN (SELECT id FROM main.meta_data WHERE value LIKE '%s'"
364 " UNION SELECT imgid AS id FROM main.tagged_images AS ti, data.tags AS t"
365 " WHERE t.id=ti.tagid AND (t.name LIKE '%s' OR t.synonyms LIKE '%s')"
366 " UNION SELECT id FROM main.images"
367 " WHERE filename LIKE '%s'"
368 " UNION SELECT i.id FROM main.images AS i, main.film_rolls AS fr"
369 " WHERE fr.id=i.film_id AND fr.folder LIKE '%s')",
405 " (SELECT imgid AS id, SUM(1 << color) AS mask FROM main.color_labels GROUP BY imgid)"
406 " WHERE ((mask & %i) > 0))",
411 " (SELECT imgid AS id, SUM(1 << color) AS mask FROM main.color_labels GROUP BY imgid)"
412 " WHERE ((mask & 31) > 0))",
429 wq = g_strdup(
" id=0");
441 selq_post =
dt_util_dstrcat(selq_post,
") AS mi LEFT OUTER JOIN main.color_labels AS b ON mi.id = b.imgid");
452 ") AS mi JOIN (SELECT id AS film_rolls_id, folder FROM main.film_rolls) ON film_id = film_rolls_id");
461 selq_post =
dt_util_dstrcat(selq_post,
") AS mi LEFT OUTER JOIN main.meta_data AS m ON mi.id = m.id AND m.key = %d ",
467 const uint32_t tagid = collection->
tagid;
468 char tag[16] = { 0 };
469 snprintf(tag,
sizeof(tag),
"%u", tagid);
472 "SELECT DISTINCT mi.id FROM (SELECT"
473 " id, group_id, film_id, filename, datetime_taken, "
474 " flags, version, %s position, aspect_ratio,"
475 " maker, model, lens, aperture, exposure, focal_length,"
476 " iso, import_timestamp, change_timestamp,"
477 " export_timestamp, print_timestamp"
478 " FROM main.images AS mi %s%s ) AS mi ",
479 tagid ?
"CASE WHEN ti.position IS NULL THEN 0 ELSE ti.position END AS" :
"",
480 tagid ?
" LEFT JOIN main.tagged_images AS ti"
481 " ON ti.imgid = mi.id AND ti.tagid = " :
"",
487 const uint32_t tagid = collection->
tagid;
488 char tag[16] = { 0 };
489 snprintf(tag,
sizeof(tag),
"%u", tagid);
492 "SELECT DISTINCT mi.id FROM (SELECT"
493 " id, group_id, film_id, filename, datetime_taken, "
494 " flags, version, %s position, aspect_ratio,"
495 " maker, model, lens, aperture, exposure, focal_length,"
496 " iso, import_timestamp, change_timestamp,"
497 " export_timestamp, print_timestamp"
498 " FROM main.images AS mi %s%s ) AS mi WHERE ",
499 tagid ?
"CASE WHEN ti.position IS NULL THEN 0 ELSE ti.position END AS" :
"",
500 tagid ?
" LEFT JOIN main.tagged_images AS ti"
501 " ON ti.imgid = mi.id AND ti.tagid = " :
"",
516 =
dt_util_dstrcat(query,
"%s%s%s %s%s", selq_pre, wq, selq_post ? selq_post :
"", sq ? sq :
"",
557 return collection->
query;
568 params->filter_flags =
flags;
580 params->text_filter = text_filter;
591 params->query_flags =
flags;
596 gchar *complete_string = NULL;
600 complete_string = g_strdup(
"");
602 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/mode%1d", exclude);
615 complete_string = g_strjoinv(complete_string, ((
dt_collection_t *)collection)->where_ext);
617 gchar *where_ext = g_strdup_printf(
"(1=1%s)", complete_string);
629 ((
dt_collection_t *)collection)->where_ext = g_strdupv(extended_where);
634 collection->
tagid = tagid;
644 if(reverse != -1) params->descending = reverse;
659 char *col_name = NULL;
698 char *setting = g_strdup_printf(
"plugins/lighttable/metadata/%s_flag",
name);
701 if(!hidden) col_name = _(
name);
722 const int local_order = collection->
params.
sort;
732 default: colname =
"";
735 sq = g_strdup_printf(
"ORDER BY %s %s", colname, order);
742 sq = g_strdup_printf(
"ORDER BY CASE WHEN flags & 8 = 8 THEN -1 ELSE flags & 7 END %s", order);
748 sq = g_strdup_printf(
"ORDER BY filename %s", order);
754 sq = g_strdup_printf(
"ORDER BY mi.id %s", order);
760 sq = g_strdup_printf(
"ORDER BY color %s", order);
766 sq = g_strdup_printf(
"ORDER BY group_id %s, mi.id-group_id != 0", order);
772 sq = g_strdup_printf(
"ORDER BY folder %s", order);
778 sq = g_strdup_printf(
"ORDER BY m.value %s", order);
786 sq = g_strdup_printf(
"ORDER BY mi.id %s", order);
793 sq =
dt_util_dstrcat(sq,
", group_id ASC, mi.id-group_id != 0, filename ASC, version ASC, mi.id ASC");
825 "SELECT COUNT(DISTINCT imgid) from memory.collected_images",
830 sqlite3_clear_bindings(stmt);
831 if(sqlite3_step(stmt) == SQLITE_ROW) count = sqlite3_column_int(stmt, 0);
832 collection->
count = count;
838 return collection->
count;
852 "SELECT imgid FROM memory.collected_images LIMIT -1, ?1",
857 sqlite3_clear_bindings(stmt);
860 while(sqlite3_step(stmt) == SQLITE_ROW)
862 const int32_t imgid = sqlite3_column_int(stmt, 0);
863 list = g_list_prepend(list, GINT_TO_POINTER(imgid));
871 "SELECT imgid FROM memory.collected_images",
876 sqlite3_clear_bindings(stmt);
878 while(sqlite3_step(stmt) == SQLITE_ROW)
880 const int32_t imgid = sqlite3_column_int(stmt, 0);
881 list = g_list_prepend(list, GINT_TO_POINTER(imgid));
886 return g_list_reverse(list);
899 sqlite3_stmt *stmt = NULL;
905 if(sqlite3_step(stmt) == SQLITE_ROW)
907 result = sqlite3_column_int(stmt, 0);
910 sqlite3_finalize(stmt);
927 GMatchInfo *match_info;
929 *number1 = *number2 = *
operator= NULL;
932 regex = g_regex_new(
"^\\s*\\[\\s*([-+]?[0-9]+\\.?[0-9]*)\\s*;\\s*([-+]?[0-9]+\\.?[0-9]*)\\s*\\]\\s*$", 0, 0, NULL);
933 g_regex_match_full(regex, input, -1, 0, 0, &match_info, NULL);
934 int match_count = g_match_info_get_match_count(match_info);
938 *number1 = g_match_info_fetch(match_info, 1);
939 *number2 = g_match_info_fetch(match_info, 2);
940 *
operator= g_strdup(
"[]");
941 g_match_info_free(match_info);
942 g_regex_unref(regex);
946 g_match_info_free(match_info);
947 g_regex_unref(regex);
950 regex = g_regex_new(
"^\\s*(=|<|>|<=|>=|<>)?\\s*([-+]?[0-9]+\\.?[0-9]*)\\s*$", 0, 0, NULL);
951 g_regex_match_full(regex, input, -1, 0, 0, &match_info, NULL);
952 match_count = g_match_info_get_match_count(match_info);
956 *
operator= g_match_info_fetch(match_info, 1);
957 *number1 = g_match_info_fetch(match_info, 2);
959 if(*
operator && strcmp(*
operator,
"") == 0)
965 g_match_info_free(match_info);
966 g_regex_unref(regex);
971 if(strlen(input) < 4)
return NULL;
975 if(strcmp(
operator,
">") == 0 || strcmp(
operator,
"<=") == 0)
980 return g_strdup(bound);
995 GMatchInfo *match_info;
997 *number1 = *number2 = *
operator= NULL;
1001 regex = g_regex_new(
"^\\s*\\[\\s*(\\d{4}[:.\\d\\s]*)\\s*;\\s*(\\d{4}[:.\\d\\s]*)\\s*\\]\\s*$", 0, 0, NULL);
1002 g_regex_match_full(regex, input, -1, 0, 0, &match_info, NULL);
1003 int match_count = g_match_info_get_match_count(match_info);
1005 if(match_count == 3)
1007 gchar *txt = g_match_info_fetch(match_info, 1);
1008 gchar *txt2 = g_match_info_fetch(match_info, 2);
1012 *
operator= g_strdup(
"[]");
1016 g_match_info_free(match_info);
1017 g_regex_unref(regex);
1021 g_match_info_free(match_info);
1022 g_regex_unref(regex);
1026 regex = g_regex_new(
"^\\s*(=|<|>|<=|>=|<>)?\\s*(\\d{4}[:.\\d\\s]*)?\\s*%?\\s*$", 0, 0, NULL);
1027 g_regex_match_full(regex, input, -1, 0, 0, &match_info, NULL);
1028 match_count = g_match_info_get_match_count(match_info);
1030 if(match_count == 3)
1032 *
operator= g_match_info_fetch(match_info, 1);
1033 gchar *txt = g_match_info_fetch(match_info, 2);
1035 if(strcmp(*
operator,
"") == 0 || strcmp(*
operator,
"=") == 0 || strcmp(*
operator,
"<>") == 0)
1047 if(
IS_NULL_PTR(*
operator)) *
operator= g_strdup(
"");
1049 g_match_info_free(match_info);
1050 g_regex_unref(regex);
1056 GMatchInfo *match_info;
1058 *number1 = *number2 = *
operator= NULL;
1061 regex = g_regex_new(
"^\\s*\\[\\s*(1/)?([0-9]+\\.?[0-9]*)(\")?\\s*;\\s*(1/)?([0-9]+\\.?[0-9]*)(\")?\\s*\\]\\s*$", 0, 0, NULL);
1062 g_regex_match_full(regex, input, -1, 0, 0, &match_info, NULL);
1063 int match_count = g_match_info_get_match_count(match_info);
1065 if(match_count == 6 || match_count == 7)
1067 gchar *n1 = g_match_info_fetch(match_info, 2);
1069 if(strstr(g_match_info_fetch(match_info, 1),
"1/") != NULL)
1070 *number1 = g_strdup_printf(
"1.0/%s", n1);
1074 gchar *n2 = g_match_info_fetch(match_info, 5);
1076 if(strstr(g_match_info_fetch(match_info, 4),
"1/") != NULL)
1077 *number2 = g_strdup_printf(
"1.0/%s", n2);
1081 *
operator= g_strdup(
"[]");
1082 g_match_info_free(match_info);
1083 g_regex_unref(regex);
1087 g_match_info_free(match_info);
1088 g_regex_unref(regex);
1091 regex = g_regex_new(
"^\\s*(=|<|>|<=|>=|<>)?\\s*(1/)?([0-9]+\\.?[0-9]*)(\")?\\s*$", 0, 0, NULL);
1092 g_regex_match_full(regex, input, -1, 0, 0, &match_info, NULL);
1093 match_count = g_match_info_get_match_count(match_info);
1094 if(match_count == 4 || match_count == 5)
1096 *
operator= g_match_info_fetch(match_info, 1);
1098 gchar *n1 = g_match_info_fetch(match_info, 3);
1100 if(strstr(g_match_info_fetch(match_info, 2),
"1/") != NULL)
1101 *number1 = g_strdup_printf(
"1.0/%s", n1);
1105 if(*
operator && strcmp(*
operator,
"") == 0)
1111 g_match_info_free(match_info);
1112 g_regex_unref(regex);
1117 gchar *needle = NULL;
1118 gboolean wildcard =
FALSE;
1120 GHashTable *names = NULL;
1122 names = g_hash_table_new(g_str_hash, g_str_equal);
1124 if (filter && filter[0] !=
'\0')
1126 needle = g_utf8_strdown(filter, -1);
1127 wildcard = (needle && needle[strlen(needle) - 1] ==
'%') ?
TRUE :
FALSE;
1129 needle[strlen(needle) - 1] =
'\0';
1135 "SELECT maker, model FROM main.images GROUP BY maker, model",
1139 sqlite3_reset(stmt);
1140 sqlite3_clear_bindings(stmt);
1141 while(sqlite3_step(stmt) == SQLITE_ROW)
1143 const char *exif_maker = (
char *)sqlite3_column_text(stmt, 0);
1144 const char *exif_model = (
char *)sqlite3_column_text(stmt, 1);
1148 gchar *haystack = g_utf8_strdown(makermodel, -1);
1149 if (
IS_NULL_PTR(needle) || (wildcard && g_strrstr(haystack, needle) != NULL)
1150 || (!wildcard && !g_strcmp0(haystack, needle)))
1155 GList *inner_list = NULL;
1156 inner_list = g_list_append(inner_list, g_strdup(exif_maker));
1157 inner_list = g_list_append(inner_list, g_strdup(exif_model));
1158 *exif = g_list_append(*exif, inner_list);
1163 gchar *
key = g_strdup(makermodel);
1164 g_hash_table_add(names,
key);
1174 *sanitized = g_list_sort(g_hash_table_get_keys(names), (GCompareFunc) strcmp);
1175 g_hash_table_destroy(names);
1188 alias,
sizeof(alias));
1191 gchar *makermodel = g_strdup_printf(
"%s %s",
maker,
model);
1196 const gboolean recursive)
1198 char *escaped_text = sqlite3_mprintf(
"%q", text);
1199 const unsigned int escaped_length = strlen(escaped_text);
1200 gchar *query = NULL;
1209 query = g_strdup_printf(
"(%s)", text);
1211 query = g_strdup(
"1=1");
1215 if(!(escaped_text && *escaped_text))
1217 query = g_strdup_printf(
"(film_id IN (SELECT id FROM main.film_rolls WHERE folder LIKE '%s%%'))",
1222 query = g_strdup_printf(
"(film_id IN (SELECT id FROM main.film_rolls WHERE folder LIKE '%s'))",
1233 const gboolean has_star = (escaped_length > 0) && (escaped_text[escaped_length-1] ==
'*');
1234 if(recursive || has_star)
1236 if(has_star) escaped_text[escaped_length-1] =
'\0';
1238 query = g_strdup_printf(
"(film_id IN (SELECT id FROM main.film_rolls WHERE folder LIKE '%s' OR folder LIKE '%s"
1239 G_DIR_SEPARATOR_S
"%%'))",
1240 escaped_text, escaped_text);
1244 else if ((escaped_length > 1) && (strcmp(escaped_text+escaped_length-2,
"|%") == 0 ))
1246 escaped_text[escaped_length-2] =
'\0';
1248 query = g_strdup_printf(
"(film_id IN (SELECT id FROM main.film_rolls WHERE folder LIKE '%s"
1249 G_DIR_SEPARATOR_S
"%%'))",
1256 query = g_strdup_printf(
"(film_id IN (SELECT id FROM main.film_rolls WHERE folder LIKE '%s'))",
1265 if(!(escaped_text && *escaped_text) || strcmp(escaped_text,
"%") == 0)
1267 query = g_strdup_printf(
"(id IN (SELECT imgid FROM main.color_labels WHERE color IS NOT NULL))");
1272 if(strcmp(escaped_text, _(
"red")) == 0)
1274 else if(strcmp(escaped_text, _(
"yellow")) == 0)
1276 else if(strcmp(escaped_text, _(
"green")) == 0)
1278 else if(strcmp(escaped_text, _(
"blue")) == 0)
1280 else if(strcmp(escaped_text, _(
"purple")) == 0)
1283 query = g_strdup_printf(
"(id IN (SELECT imgid FROM main.color_labels WHERE color=%d))", color);
1291 if(strcmp(escaped_text, _(
"altered")) == 0)
1293 query = g_strdup(
"EXISTS (SELECT 1 FROM main.history h WHERE h.imgid = id)");
1295 else if(strcmp(escaped_text, _(
"unaltered")) == 0)
1297 query = g_strdup(
"NOT EXISTS (SELECT 1 FROM main.history h WHERE h.imgid = id)");
1301 query = g_strdup(
"1");
1308 const gboolean not_tagged = strcmp(escaped_text, _(
"not tagged")) == 0;
1309 const gboolean no_location = strcmp(escaped_text, _(
"tagged")) == 0;
1310 const gboolean all_tagged = strcmp(escaped_text, _(
"tagged*")) == 0;
1311 char *escaped_text2 = g_strstr_len(escaped_text, -1,
"|");
1312 char *name_clause = g_strdup_printf(
"t.name LIKE \'%s\' || \'%s\'",
1315 if (escaped_text2 && (escaped_text2[strlen(escaped_text2)-1] ==
'*'))
1317 escaped_text2[strlen(escaped_text2)-1] =
'\0';
1318 name_clause = g_strdup_printf(
"(t.name LIKE \'%s\' || \'%s\' OR t.name LIKE \'%s\' || \'%s|%%\')",
1322 if(not_tagged || all_tagged)
1324 query = g_strdup_printf(
"(id %s IN (SELECT id AS imgid FROM main.images "
1325 "WHERE (longitude IS NOT NULL AND latitude IS NOT NULL))) ",
1326 all_tagged ?
"" :
"not");
1330 query = g_strdup_printf(
"(id IN (SELECT id AS imgid FROM main.images "
1331 "WHERE (longitude IS NOT NULL AND latitude IS NOT NULL))"
1332 "AND id %s IN (SELECT imgid FROM main.tagged_images AS ti"
1333 " JOIN data.tags AS t"
1334 " ON t.id = ti.tagid"
1336 no_location ?
"not" :
"",
1344 query = g_strdup_printf(
"(id %s IN (SELECT id AS imgid FROM main.images WHERE (flags & %d))) ",
1345 (strcmp(escaped_text, _(
"not copied locally")) == 0) ?
"not" :
"",
1352 query = g_strdup_printf(
"((1=0)");
1353 GList *lists = NULL;
1355 for(GList *element = lists; element; element = g_list_next(element))
1357 GList *tuple = element->data;
1358 char *clause = sqlite3_mprintf(
" OR (maker = '%q' AND model = '%q')", tuple->data, tuple->next->data);
1360 sqlite3_free(clause);
1373 if(!strcmp(escaped_text, _(
"not tagged")))
1376 query = g_strdup_printf(
"(id NOT IN (SELECT DISTINCT imgid FROM main.tagged_images "
1377 "WHERE tagid NOT IN memory.darktable_tags))");
1382 if ((escaped_length > 0) && (escaped_text[escaped_length-1] ==
'*'))
1386 escaped_text[escaped_length-1] =
'\0';
1388 query = g_strdup_printf(
"(id IN (SELECT imgid FROM main.tagged_images WHERE tagid IN "
1389 "(SELECT id FROM data.tags "
1390 "WHERE LOWER(name) = LOWER('%s')"
1391 " OR SUBSTR(LOWER(name), 1, LENGTH('%s') + 1) = LOWER('%s|'))))",
1392 escaped_text, escaped_text, escaped_text);
1395 else if ((escaped_length > 0) && (escaped_text[escaped_length-1] ==
'%'))
1398 escaped_text[escaped_length-1] =
'\0';
1400 query = g_strdup_printf(
"(id IN (SELECT imgid FROM main.tagged_images WHERE tagid IN "
1401 "(SELECT id FROM data.tags WHERE SUBSTR(LOWER(name), 1, LENGTH('%s')) = LOWER('%s'))))",
1402 escaped_text, escaped_text);
1409 query = g_strdup_printf(
"(id IN (SELECT imgid FROM main.tagged_images WHERE tagid IN "
1410 "(SELECT id FROM data.tags WHERE LOWER(name) = LOWER('%s'))))",
1419 query = g_strdup_printf(
"(lens LIKE '%%%s%%')", escaped_text);
1424 gchar *
operator, *number1, *number2;
1427 if(
operator && strcmp(
operator,
"[]") == 0)
1429 if(number1 && number2)
1430 query = g_strdup_printf(
"((focal_length >= %s) AND (focal_length <= %s))", number1, number2);
1432 else if(
operator && number1)
1433 query = g_strdup_printf(
"(focal_length %s %s)",
operator, number1);
1436 query = g_strdup_printf(
"(CAST(focal_length AS INTEGER) = CAST(%s AS INTEGER))", number1);
1439 query = g_strdup_printf(
"(focal_length LIKE '%%%s%%')", escaped_text);
1449 gchar *
operator, *number1, *number2;
1452 if(
operator && strcmp(
operator,
"[]") == 0)
1454 if(number1 && number2)
1455 query = g_strdup_printf(
"((iso >= %s) AND (iso <= %s))", number1, number2);
1457 else if(
operator && number1)
1458 query = g_strdup_printf(
"(iso %s %s)",
operator, number1);
1460 query = g_strdup_printf(
"(iso = %s)", number1);
1462 query = g_strdup_printf(
"(iso LIKE '%%%s%%')", escaped_text);
1472 gchar *
operator, *number1, *number2;
1475 if(
operator && strcmp(
operator,
"[]") == 0)
1477 if(number1 && number2)
1479 query = g_strdup_printf(
"((ROUND(aperture,1) >= %s) AND (ROUND(aperture,1) <= %s))", number1,
1483 else if(
operator && number1)
1484 query = g_strdup_printf(
"(ROUND(aperture,1) %s %s)",
operator, number1);
1486 query = g_strdup_printf(
"(ROUND(aperture,1) = %s)", number1);
1488 query = g_strdup_printf(
"(ROUND(aperture,1) LIKE '%%%s%%')", escaped_text);
1498 gchar *
operator, *number1, *number2;
1501 if(
operator && strcmp(
operator,
"[]") == 0)
1503 if(number1 && number2)
1505 query = g_strdup_printf(
"((exposure >= %s - 1.0/100000) AND (exposure <= %s + 1.0/100000))", number1,
1509 else if(
operator && number1)
1510 query = g_strdup_printf(
"(exposure %s %s)",
operator, number1);
1513 query = g_strdup_printf(
"(CASE WHEN exposure < 0.4 THEN ((exposure >= %s - 1.0/100000) AND (exposure <= %s + 1.0/100000)) "
1514 "ELSE (ROUND(exposure,2) >= %s - 1.0/100000) AND (ROUND(exposure,2) <= %s + 1.0/100000) END)",
1515 number1, number1, number1, number1);
1518 query = g_strdup_printf(
"(exposure LIKE '%%%s%%')", escaped_text);
1530 for (GList *l = list; l; l = g_list_next(l))
1532 char *
name = (
char*)l->data;
1533 l->data = g_strdup_printf(
"(filename LIKE '%%%s%%')",
name);
1538 query = g_strdup_printf(
"(%s)", subquery);
1552 const int local_property = property;
1553 char *colname = NULL;
1555 switch(local_property)
1564 gchar *
operator, *number1, *number2;
1566 if(number1 && number1[strlen(number1) - 1] ==
'%')
1567 number1[strlen(number1) - 1] =
'\0';
1571 if(strcmp(
operator,
"[]") == 0)
1573 if(number1 && number2)
1574 query = g_strdup_printf(
"((%s >= %" G_GINT64_FORMAT
") AND (%s <= %" G_GINT64_FORMAT
"))", colname, nb1, colname, nb2);
1576 else if((strcmp(
operator,
"=") == 0 || strcmp(
operator,
"") == 0) && number1 && number2)
1577 query = g_strdup_printf(
"((%s >= %" G_GINT64_FORMAT
") AND (%s <= %" G_GINT64_FORMAT
"))", colname, nb1, colname, nb2);
1578 else if(strcmp(
operator,
"<>") == 0 && number1 && number2)
1581 query = g_strdup_printf(
"((%s < %" G_GINT64_FORMAT
") OR (%s > %" G_GINT64_FORMAT
"))", colname, nb1, colname, nb2);
1583 query = g_strdup_printf(
"(%s %s %" G_GINT64_FORMAT
")", colname,
operator, nb1);
1585 query = g_strdup(
"1 = 1");
1594 query = g_strdup_printf(
"(id %s group_id)", (strcmp(escaped_text, _(
"group leaders")) == 0) ?
"=" :
"!=");
1600 query = g_strdup_printf(
"(id IN (SELECT imgid AS id FROM main.history AS h "
1601 "JOIN memory.darktable_iop_names AS m ON m.operation = h.operation "
1602 "WHERE h.enabled = 1 AND m.name LIKE '%s'))", escaped_text);
1616 query = g_strdup_printf(
"(id IN (SELECT imgid FROM main.module_order WHERE version = %d))",
i);
1620 query = g_strdup_printf(
"(id NOT IN (SELECT imgid FROM main.module_order))");
1627 gchar *
operator, *number1, *number2;
1630 if(
operator && strcmp(
operator,
"[]") == 0)
1632 if(number1 && number2)
1634 if(atoi(number1) == -1)
1637 query = g_strdup_printf(
"(flags & 7 >= %s AND flags & 7 <= %s)", number1, number2);
1643 query = g_strdup_printf(
"((flags & 8 == 0) AND (flags & 7 >= %s AND flags & 7 <= %s))", number1, number2);
1648 else if(
operator && number1)
1650 if(g_strcmp0(
operator,
"<=") == 0 || g_strcmp0(
operator,
"<") == 0)
1653 query = g_strdup_printf(
"(flags & 8 == 8 OR flags & 7 %s %s)",
operator, number1);
1656 else if(g_strcmp0(
operator,
">=") == 0 || g_strcmp0(
operator,
">") == 0)
1658 if(atoi(number1) >= 0)
1661 query = g_strdup_printf(
"(flags & 8 == 0 AND flags & 7 %s %s)",
operator, number1);
1668 if(atoi(number1) == -1)
1670 query = g_strdup_printf(
"(flags & 8 == 0)");
1674 query = g_strdup_printf(
"(flags & 8 == 8 OR flags & 7 %s %s)",
operator, number1);
1680 if(atoi(number1) == -1)
1682 query = g_strdup_printf(
"(flags & 8 == 8)");
1686 query = g_strdup_printf(
"(flags & 8 == 0 AND flags & 7 == %s)", number1);
1702 if(strcmp(escaped_text, _(
"not defined")) != 0)
1704 query = g_strdup_printf(
"(id IN (SELECT id FROM main.meta_data WHERE key = %d AND value "
1705 "LIKE '%%%s%%'))", keyid, escaped_text);
1709 query = g_strdup_printf(
"(id NOT IN (SELECT id FROM main.meta_data WHERE key = %d))",
1716 sqlite3_free(escaped_text);
1719 query = g_strdup_printf(
"(1=1)");
1730 GList *result = NULL;
1734 gchar *query = g_strdup_printf(
"SELECT id FROM main.images WHERE %s", where);
1737 sqlite3_stmt *stmt = NULL;
1741 while(sqlite3_step(stmt) == SQLITE_ROW)
1742 result = g_list_prepend(result, GINT_TO_POINTER(sqlite3_column_int(stmt, 0)));
1743 sqlite3_finalize(stmt);
1747 return g_list_reverse(result);
1776 gchar *q = g_strdup_printf(
"SELECT maker, model, COUNT(*) AS count FROM main.images AS mi"
1777 " WHERE %s GROUP BY maker, model", where_ext);
1779 sqlite3_stmt *stmt = NULL;
1782 while(stmt && sqlite3_step(stmt) == SQLITE_ROW)
1784 const char *
maker = (
const char *)sqlite3_column_text(stmt, 0);
1785 const char *
model = (
const char *)sqlite3_column_text(stmt, 1);
1789 if(stmt) sqlite3_finalize(stmt);
1791 return g_list_reverse(
out);
1799 const gboolean has_status
1801 gchar *query = NULL;
1806 query = g_strdup_printf(
"SELECT folder, film_rolls_id, COUNT(*) AS count, status"
1807 " FROM main.images AS mi"
1808 " JOIN (SELECT fr.id AS film_rolls_id, folder, status"
1809 " FROM main.film_rolls AS fr"
1810 " JOIN memory.film_folder AS ff ON fr.id = ff.id)"
1811 " ON film_id = film_rolls_id"
1812 " WHERE %s GROUP BY folder, film_rolls_id", where_ext);
1816 query = g_strdup_printf(
"SELECT name, 1 AS tagid, SUM(count) AS count"
1817 " FROM (SELECT tagid, COUNT(*) as count"
1818 " FROM main.images AS mi JOIN main.tagged_images ON id = imgid"
1819 " WHERE %s GROUP BY tagid)"
1820 " JOIN (SELECT name, id AS tag_id FROM data.tags)"
1821 " ON tagid = tag_id GROUP BY name", where_ext);
1823 "SELECT '%s' AS name, 0 as id, COUNT(*) AS count "
1824 "FROM main.images AS mi WHERE mi.id NOT IN"
1825 " (SELECT DISTINCT imgid FROM main.tagged_images AS ti"
1826 " WHERE ti.tagid NOT IN memory.darktable_tags)",
1831 query = g_strdup_printf(
"SELECT CASE WHEN mi.longitude IS NULL OR mi.latitude IS null THEN '%s'"
1832 " ELSE CASE WHEN ta.imgid IS NULL THEN '%s' ELSE '%s' || ta.tagname END"
1833 " END AS name, ta.tagid AS tag_id, COUNT(*) AS count"
1834 " FROM main.images AS mi"
1835 " LEFT JOIN (SELECT imgid, t.id AS tagid, SUBSTR(t.name, %d) AS tagname"
1836 " FROM main.tagged_images AS ti JOIN data.tags AS t ON ti.tagid = t.id"
1837 " JOIN data.locations AS l ON l.tagid = t.id) AS ta ON ta.imgid = mi.id"
1838 " WHERE %s GROUP BY name, tag_id",
1839 _(
"not tagged"), _(
"tagged"), _(
"tagged"),
1844 query = g_strdup_printf(
"SELECT (datetime_taken / 86400000000) * 86400000000 AS date, 1, COUNT(*) AS count"
1845 " FROM main.images AS mi"
1846 " WHERE datetime_taken IS NOT NULL AND datetime_taken <> 0 AND %s"
1847 " GROUP BY date", where_ext);
1856 char *colname = NULL;
1866 query = g_strdup_printf(
"SELECT %s AS date, 1, COUNT(*) AS count FROM main.images AS mi"
1867 " WHERE %s IS NOT NULL AND %s <> 0 AND %s GROUP BY date",
1868 colname, colname, colname, where_ext);
1873 query = g_strdup_printf(
"SELECT CASE WHEN EXISTS (SELECT 1 FROM main.history h WHERE h.imgid = mi.id)"
1874 " THEN '%s' ELSE '%s' END as altered, 1, COUNT(*) AS count"
1875 " FROM main.images AS mi WHERE %s GROUP BY altered ORDER BY altered ASC",
1876 _(
"altered"), _(
"unaltered"), where_ext);
1880 query = g_strdup_printf(
"SELECT CASE WHEN (flags & %d) THEN '%s' ELSE '%s' END as lcp, 1, COUNT(*) AS count"
1881 " FROM main.images AS mi WHERE %s GROUP BY lcp ORDER BY lcp ASC",
1886 query = g_strdup_printf(
"SELECT CASE color WHEN 0 THEN '%s' WHEN 1 THEN '%s' WHEN 2 THEN '%s'"
1887 " WHEN 3 THEN '%s' WHEN 4 THEN '%s' ELSE '' END, color, COUNT(*) AS count"
1888 " FROM main.images AS mi"
1889 " JOIN (SELECT imgid AS color_labels_id, color FROM main.color_labels)"
1890 " ON id = color_labels_id WHERE %s GROUP BY color ORDER BY color DESC",
1891 _(
"red"), _(
"yellow"), _(
"green"), _(
"blue"), _(
"purple"), where_ext);
1895 query = g_strdup_printf(
"SELECT lens, 1, COUNT(*) AS count FROM main.images AS mi WHERE %s"
1896 " GROUP BY lens ORDER BY lens", where_ext);
1900 query = g_strdup_printf(
"SELECT CAST(focal_length AS INTEGER) AS focal_length, 1, COUNT(*) AS count"
1901 " FROM main.images AS mi WHERE %s GROUP BY CAST(focal_length AS INTEGER)"
1902 " ORDER BY CAST(focal_length AS INTEGER)", where_ext);
1906 query = g_strdup_printf(
"SELECT CAST(iso AS INTEGER) AS iso, 1, COUNT(*) AS count"
1907 " FROM main.images AS mi WHERE %s GROUP BY iso ORDER BY iso", where_ext);
1911 query = g_strdup_printf(
"SELECT ROUND(aperture,1) AS aperture, 1, COUNT(*) AS count"
1912 " FROM main.images AS mi WHERE %s GROUP BY aperture ORDER BY aperture", where_ext);
1916 query = g_strdup_printf(
"SELECT CASE WHEN (exposure < 0.4) THEN '1/' || CAST(1/exposure + 0.9 AS INTEGER)"
1917 " ELSE ROUND(exposure,2) || '\"' END as _exposure, 1, COUNT(*) AS count"
1918 " FROM main.images AS mi WHERE %s GROUP BY _exposure ORDER BY exposure", where_ext);
1922 query = g_strdup_printf(
"SELECT filename, 1, COUNT(*) AS count FROM main.images AS mi WHERE %s"
1923 " GROUP BY filename ORDER BY filename", where_ext);
1927 query = g_strdup_printf(
"SELECT CASE WHEN id = group_id THEN '%s' ELSE '%s' END as group_leader, 1,"
1928 " COUNT(*) AS count FROM main.images AS mi WHERE %s"
1929 " GROUP BY group_leader ORDER BY group_leader ASC",
1930 _(
"group leaders"), _(
"group followers"), where_ext);
1934 query = g_strdup_printf(
"SELECT m.name AS module_name, 1, COUNT(*) AS count FROM main.images AS mi"
1935 " JOIN (SELECT DISTINCT imgid, operation FROM main.history WHERE enabled = 1) AS h"
1936 " ON h.imgid = mi.id JOIN memory.darktable_iop_names AS m"
1937 " ON m.operation = h.operation WHERE %s GROUP BY module_name ORDER BY module_name",
1947 query = g_strdup_printf(
"SELECT CASE %s END as ver, 1, COUNT(*) AS count FROM main.images AS mi"
1948 " LEFT JOIN (SELECT imgid, version FROM main.module_order) mo ON mo.imgid = mi.id"
1949 " WHERE %s GROUP BY ver ORDER BY ver",
orders, where_ext);
1955 query = g_strdup_printf(
"SELECT CASE WHEN (flags & 8) == 8 THEN -1 ELSE (flags & 7) END AS rating, 1,"
1956 " COUNT(*) AS count FROM main.images AS mi WHERE %s GROUP BY rating ORDER BY rating",
1965 char *setting = g_strdup_printf(
"plugins/lighttable/metadata/%s_flag",
name);
1969 query = g_strdup_printf(
"SELECT CASE WHEN value IS NULL THEN '%s' ELSE value END AS value, 1,"
1970 " COUNT(*) AS count, CASE WHEN value IS NULL THEN 0 ELSE 1 END AS force_order"
1971 " FROM main.images AS mi"
1972 " LEFT JOIN (SELECT id AS meta_data_id, value FROM main.meta_data WHERE key = %d)"
1973 " ON id = meta_data_id WHERE %s GROUP BY value ORDER BY force_order, value",
1974 _(
"not defined"), keyid, where_ext);
1978 gchar *order_by = NULL;
1980 if(strcmp(filmroll_sort,
"id") == 0)
1981 order_by = g_strdup(
"film_rolls_id DESC");
1983 order_by =
dt_conf_get_bool(
"plugins/collect/descending") ? g_strdup(
"folder DESC") : g_strdup(
"folder");
1984 query = g_strdup_printf(
"SELECT folder, film_rolls_id, COUNT(*) AS count, status FROM main.images AS mi"
1985 " JOIN (SELECT fr.id AS film_rolls_id, folder, status FROM main.film_rolls AS fr"
1986 " JOIN memory.film_folder AS ff ON ff.id = fr.id) ON film_id = film_rolls_id"
1987 " WHERE %s GROUP BY folder ORDER BY %s", where_ext, order_by);
1993 if(!query)
return NULL;
1995 sqlite3_stmt *stmt = NULL;
1997 while(stmt && sqlite3_step(stmt) == SQLITE_ROW)
2005 name = g_strdup(sdt);
2009 const char *txt = (
const char *)sqlite3_column_text(stmt, 0);
2010 name = txt ? g_strdup(txt) : g_strdup(
"");
2012 const int id = sqlite3_column_int(stmt, 1);
2013 const int count = sqlite3_column_int(stmt, 2);
2014 const int status = has_status ? sqlite3_column_int(stmt, 3) : -1;
2017 if(stmt) sqlite3_finalize(stmt);
2019 return g_list_reverse(
out);
2026 const int num_rules =
dt_conf_get_int(
"plugins/lighttable/collect/num_rules");
2027 c = snprintf(buf, bufsize,
"%d:", num_rules);
2030 for(
int k = 0;
k < num_rules;
k++)
2032 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/mode%1d",
k);
2034 c = snprintf(buf, bufsize,
"%d:", mode);
2037 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/item%1d",
k);
2039 c = snprintf(buf, bufsize,
"%d:", item);
2042 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/string%1d",
k);
2047 gchar *str_recursive = NULL;
2050 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/recursive%1d",
k);
2051 if(
dt_conf_get_bool(confname)) str_recursive = g_strconcat(str,
"*", NULL);
2053 const char *emit = str_recursive ? str_recursive : str;
2054 if(emit && (emit[0] !=
'\0'))
2055 c = snprintf(buf, bufsize,
"%s$", emit);
2057 c = snprintf(buf, bufsize,
"%%$");
2058 g_free(str_recursive);
2068 sscanf(buf,
"%d", &num_rules);
2079 int mode = 0, item = 0;
2081 while(buf[0] !=
'\0' && buf[0] !=
':') buf++;
2082 if(buf[0] ==
':') buf++;
2083 char str[400], confname[200];
2084 for(
int k = 0;
k < num_rules;
k++)
2086 const int n = sscanf(buf,
"%d:%d:%399[^$]", &mode, &item, str);
2089 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/mode%1d",
k);
2091 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/item%1d",
k);
2098 const size_t len = strlen(str);
2099 const gboolean recursive = len > 0 && str[len - 1] ==
'*';
2100 if(recursive) str[len - 1] =
'\0';
2101 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/recursive%1d",
k);
2104 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/string%1d",
k);
2107 else if(num_rules == 1)
2109 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/mode%1d",
k);
2111 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/item%1d",
k);
2113 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/string%1d",
k);
2115 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/recursive%1d",
k);
2124 while(buf[0] !=
'$' && buf[0] !=
'\0') buf++;
2125 if(buf[0] ==
'$') buf++;
2138 char confname[200] = { 0 };
2143 gboolean found_duplicate =
FALSE;
2146 int num_items =
dt_conf_get_int(
"plugins/lighttable/recentcollect/num_items");
2147 for(
int k = 0;
k < num_items;
k++)
2149 snprintf(confname,
sizeof(confname),
"plugins/lighttable/recentcollect/line%1d",
k);
2152 if(!strcmp(line, buf))
2155 found_duplicate =
TRUE;
2163 const int max_items = CLAMP(
dt_conf_get_int(
"plugins/lighttable/recentcollect/max_items"), 1,
2165 int shifted_index =
MIN(num_items - (found_duplicate ? 1 : 0), max_items);
2166 for(
int k = num_items - 1;
k > -1;
k--)
2168 if(
k ==
n)
continue;
2171 snprintf(confname,
sizeof(confname),
"plugins/lighttable/recentcollect/line%1d",
k);
2173 snprintf(confname,
sizeof(confname),
"plugins/lighttable/recentcollect/pos%1d",
k);
2183 if(shifted_index >= 0 && shifted_index < max_items)
2185 snprintf(confname,
sizeof(confname),
"plugins/lighttable/recentcollect/line%1d", shifted_index);
2187 snprintf(confname,
sizeof(confname),
"plugins/lighttable/recentcollect/pos%1d", shifted_index);
2198 num_items += found_duplicate ? 0 : 1;
2199 dt_conf_set_int(
"plugins/lighttable/recentcollect/num_items", CLAMP(num_items, 1, max_items));
2215 for(GList *l = list; l; l = g_list_next(l))
2217 const int id = GPOINTER_TO_INT(l->data);
2227 gchar *query = g_strdup_printf(
"SELECT imgid"
2228 " FROM memory.collected_images"
2229 " WHERE imgid NOT IN (%s)"
2230 " AND rowid > (SELECT rowid"
2231 " FROM memory.collected_images"
2232 " WHERE imgid IN (%s)"
2233 " ORDER BY rowid LIMIT 1)"
2234 " ORDER BY rowid LIMIT 1",
2237 sqlite3_stmt *stmt2;
2239 if(sqlite3_step(stmt2) == SQLITE_ROW)
2241 next = sqlite3_column_int(stmt2, 0);
2243 sqlite3_finalize(stmt2);
2249 query = g_strdup_printf(
"SELECT imgid"
2250 " FROM memory.collected_images"
2251 " WHERE imgid NOT IN (%s)"
2252 " AND rowid < (SELECT rowid"
2253 " FROM memory.collected_images"
2254 " WHERE imgid IN (%s)"
2255 " ORDER BY rowid LIMIT 1)"
2256 " ORDER BY rowid DESC LIMIT 1",
2260 if(sqlite3_step(stmt2) == SQLITE_ROW)
2262 next = sqlite3_column_int(stmt2, 0);
2264 sqlite3_finalize(stmt2);
2272 const int _n_r =
dt_conf_get_int(
"plugins/lighttable/collect/num_rules");
2273 const int num_rules = CLAMP(_n_r, 1, 10);
2274 char *conj[] = {
"AND",
"OR",
"AND NOT" };
2276 gchar **query_parts = g_new (gchar*, num_rules + 1);
2277 query_parts[num_rules] = NULL;
2279 for(
int i = 0;
i < num_rules;
i++)
2281 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/item%1d",
i);
2283 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/string%1d",
i);
2285 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/mode%1d",
i);
2287 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/recursive%1d",
i);
2293 query_parts[
i] = g_strdup(
" OR 1=1");
2295 query_parts[
i] = g_strdup(
"");
2301 query_parts[
i] = g_strdup_printf(
" %s %s", conj[mode], query);
2310 g_strfreev(query_parts);
2332 "INSERT INTO memory.collected_images"
2333 " SELECT * FROM memory.collected_backup",
2342 "INSERT INTO memory.collected_backup"
2343 " SELECT * FROM memory.collected_images",
2354 "DELETE FROM memory.collected_images"
2355 " WHERE imgid NOT IN "
2356 " (SELECT imgid FROM main.selected_images)",
2395 selected = GPOINTER_TO_INT(selected_imgids->data);
2399 g_list_free(selected_imgids);
2400 selected_imgids = NULL;
2401 message = g_strdup_printf(_(
"%d image of %d (#%d) in current collection is selected"), cs, c, selected);
2405 message = g_strdup_printf(
2407 "%d image of %d in current collection is selected",
2408 "%d images of %d in current collection are selected",
2423 "SELECT imgid FROM memory.collected_images",
2427 sqlite3_reset(stmt);
2428 sqlite3_clear_bindings(stmt);
2430 gboolean found =
FALSE;
2432 while(sqlite3_step(stmt) == SQLITE_ROW)
2434 const int id = sqlite3_column_int(stmt, 0);
2443 if(!found) offset = 0;
2454 if(!g_strcmp0(current_view->
module_name,
"studio_capture"))
return;
2456 if(open_single_image)
2458 if(!g_strcmp0(current_view->
module_name,
"darkroom"))
2463 else if(g_strcmp0(current_view->
module_name,
"lighttable"))
2477 result |= current_atelier && g_strcmp0(current_atelier->
module_name,
"lighttable")
2478 && g_strcmp0(current_atelier->
module_name,
"studio_capture");
2483 const gboolean is_lighttable = current_atelier && !g_strcmp0(current_atelier->
module_name,
"lighttable");
2498 gchar first_directory[
PATH_MAX] = { 0 };
2521 fprintf(stdout,
"Collection: one folder.\n");
2522 g_strlcpy(dir, g_strdup(first_selection),
sizeof(dir));
2526 fprintf(stdout,
"Collection: files and folders.\n");
2529 g_strlcpy(dir, g_strdup(import_last_dir),
sizeof(dir));
2534 fprintf(stdout,
"Collection: copy or in List view.\n");
2536 gchar first_img_path[
PATH_MAX] = { 0 };
2541 g_strlcpy(dir, first_img_path,
sizeof(dir));
2542 fprintf(stdout,
"Collection: ID %d, last img path %s.\n", imgid, first_img_path);
const char * dt_collection_name(dt_collection_properties_t prop)
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)
void dt_culling_mode_to_selection()
void dt_collection_reset(const dt_collection_t *collection)
void dt_collection_set_query_flags(const dt_collection_t *collection, dt_collection_query_flags_t flags)
void dt_collection_deserialize(const char *buf)
const dt_collection_params_t * dt_collection_params(const dt_collection_t *collection)
static char * _dt_collection_compute_datetime(const char *operator, const char *input)
void dt_collection_split_operator_exposure(const gchar *input, char **number1, char **number2, char **operator)
void dt_collection_set_text_filter(const dt_collection_t *collection, char *text_filter)
static int dt_collection_image_offset_with_collection(const dt_collection_t *collection, int32_t imgid)
char * dt_collection_get_text_filter(const dt_collection_t *collection)
gboolean dt_collection_get_sort_descending(const dt_collection_t *collection)
gchar * dt_collection_get_extended_where(const dt_collection_t *collection, int exclude)
void dt_selection_to_culling_mode()
static sqlite3_stmt * _collection_count_stmt
static dt_collection_name_value_t * _name_value_new(char *name, int id, int count, int status)
GList * dt_collection_get(const dt_collection_t *collection, int limit)
void dt_collection_set_filter_flags(const dt_collection_t *collection, dt_collection_filter_flag_t flags)
void dt_collection_memory_update()
static char * or_operator(int *term)
void dt_collection_split_operator_number(const gchar *input, char **number1, char **number2, char **operator)
dt_collection_filter_flag_t dt_collection_get_filter_flags(const dt_collection_t *collection)
void dt_collection_get_makermodels(const gchar *filter, GList **sanitized, GList **exif)
const gchar * dt_collection_get_query(const dt_collection_t *collection)
GList * dt_collection_get_images_for_rule(const dt_collection_properties_t property, const char *text, gboolean recursive)
static sqlite3_stmt * _collection_get_makermodels_stmt
static void _dt_collection_set_selq_pre_sort(const dt_collection_t *collection, char **selq_pre)
dt_collection_query_flags_t dt_collection_get_query_flags(const dt_collection_t *collection)
dt_collection_sort_t dt_collection_get_sort_field(const dt_collection_t *collection)
void dt_collection_set_tag_id(dt_collection_t *collection, const uint32_t tagid)
void dt_collection_name_value_free(gpointer value)
static void _update_recentcollections()
int dt_collection_get_nth(const dt_collection_t *collection, int nth)
static int _dt_collection_store(const dt_collection_t *collection, gchar *query)
gchar * dt_collection_get_makermodel(const char *exif_maker, const char *exif_model)
gboolean dt_collection_hint_message_internal(void *message)
void dt_push_collection()
static gboolean _collection_can_switch_folder(const int32_t imgid, const dt_view_t *current_atelier)
#define or_operator_initial()
void dt_collection_split_operator_datetime(const gchar *input, char **number1, char **number2, char **operator)
void dt_collection_hint_message(const dt_collection_t *collection)
int dt_collection_serialize(char *buf, int bufsize)
static sqlite3_stmt * _collection_get_limit_stmt
static char * and_operator(int *term)
void dt_collection_set_sort(const dt_collection_t *collection, dt_collection_sort_t sort, gboolean reverse)
static void _dt_collection_change_view_after_import(const dt_view_t *current_view, gboolean open_single_image)
static uint32_t _dt_collection_compute_count(dt_collection_t *collection)
uint32_t dt_collection_get_count(const dt_collection_t *collection)
static gchar * get_query_string(const dt_collection_properties_t property, const gchar *text, const gboolean recursive)
int dt_collection_update(const dt_collection_t *collection)
static sqlite3_stmt * _collection_get_stmt
dt_collection_t * dt_collection_new()
static sqlite3_stmt * _collection_image_offset_stmt
void dt_collection_set_extended_where(const dt_collection_t *collection, gchar **extended_where)
GList * dt_collection_get_property_values(const dt_collection_properties_t property, const int rule)
GList * dt_collection_get_all(const dt_collection_t *collection, int limit)
gchar * dt_collection_get_sort_query(const dt_collection_t *collection)
void dt_collection_free(const dt_collection_t *collection)
dt_collection_properties_t
@ DT_COLLECTION_PROP_EXPOSURE
@ DT_COLLECTION_PROP_MODULE
@ DT_COLLECTION_PROP_RATING
@ DT_COLLECTION_PROP_QUERY
@ DT_COLLECTION_PROP_TIME
@ DT_COLLECTION_PROP_METADATA
@ DT_COLLECTION_PROP_GROUPING
@ DT_COLLECTION_PROP_FILMROLL
@ DT_COLLECTION_PROP_LENS
@ DT_COLLECTION_PROP_CAMERA
@ DT_COLLECTION_PROP_LAST
@ DT_COLLECTION_PROP_LOCAL_COPY
@ DT_COLLECTION_PROP_GEOTAGGING
@ DT_COLLECTION_PROP_FILENAME
@ DT_COLLECTION_PROP_COLORLABEL
@ DT_COLLECTION_PROP_UNDEF
@ DT_COLLECTION_PROP_ORDER
@ DT_COLLECTION_PROP_FOLDERS
@ DT_COLLECTION_PROP_APERTURE
@ DT_COLLECTION_PROP_IMPORT_TIMESTAMP
@ DT_COLLECTION_PROP_FOCAL_LENGTH
@ DT_COLLECTION_PROP_EXPORT_TIMESTAMP
@ DT_COLLECTION_PROP_CHANGE_TIMESTAMP
@ DT_COLLECTION_PROP_HISTORY
@ DT_COLLECTION_PROP_PRINT_TIMESTAMP
dt_collection_query_flags_t
@ COLLECTION_QUERY_USE_ONLY_WHERE_EXT
@ COLLECTION_QUERY_USE_WHERE_EXT
@ COLLECTION_QUERY_USE_SORT
@ COLLECTION_QUERY_USE_LIMIT
#define COLLECTION_QUERY_FULL
dt_collection_filter_flag_t
@ COLLECTION_FILTER_ALTERED
@ COLLECTION_FILTER_UNALTERED
@ COLLECTION_FILTER_GREEN
@ COLLECTION_FILTER_2_STAR
@ COLLECTION_FILTER_MAGENTA
@ COLLECTION_FILTER_0_STAR
@ COLLECTION_FILTER_1_STAR
@ COLLECTION_FILTER_5_STAR
@ COLLECTION_FILTER_YELLOW
@ COLLECTION_FILTER_REJECTED
@ COLLECTION_FILTER_4_STAR
@ COLLECTION_FILTER_3_STAR
@ COLLECTION_FILTER_WHITE
@ DT_COLLECTION_CHANGE_NEW_QUERY
#define NUM_LAST_COLLECTIONS
@ DT_COLLECTION_SORT_EXPORT_TIMESTAMP
@ DT_COLLECTION_SORT_IMPORT_TIMESTAMP
@ DT_COLLECTION_SORT_DATETIME
@ DT_COLLECTION_SORT_GROUP
@ DT_COLLECTION_SORT_FILENAME
@ DT_COLLECTION_SORT_RATING
@ DT_COLLECTION_SORT_PATH
@ DT_COLLECTION_SORT_TITLE
@ DT_COLLECTION_SORT_CHANGE_TIMESTAMP
@ DT_COLLECTION_SORT_NONE
@ DT_COLLECTION_SORT_PRINT_TIMESTAMP
@ DT_COLLECTION_SORT_COLOR
const dt_colormatrix_t dt_aligned_pixel_t out
void dt_get_dirname_from_imgid(gchar *dir, const int32_t imgid)
const char * dt_map_location_data_tag_root()
void dt_conf_set_bool(const char *name, int val)
int dt_conf_get_bool(const char *name)
gchar * dt_conf_get_string(const char *name)
void dt_conf_set_int(const char *name, int val)
int dt_conf_get_int(const char *name)
void dt_conf_set_string(const char *name, const char *val)
const char * dt_conf_get_string_const(const char *name)
void dt_ctl_switch_mode_to(const char *mode)
void dt_control_set_mouse_over_id(int32_t value)
void dt_ctl_reload_view(const char *mode)
void dt_control_hinter_message(const struct dt_control_t *s, const char *message)
static void dt_free_gpointer(gpointer ptr)
static const dt_aligned_pixel_simd_t value
#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)
GTimeSpan dt_datetime_exif_to_gtimespan(const char *sdt)
gboolean dt_datetime_gtimespan_to_exif(char *sdt, const size_t sdt_size, const GTimeSpan gts)
gboolean dt_datetime_entry_to_exif_upper_bound(char *exif, const size_t exif_size, const char *entry)
gboolean dt_datetime_entry_to_exif(char *exif, const size_t exif_size, const char *entry)
#define DT_DATETIME_LENGTH
#define DT_DATETIME_EXIF_LENGTH
#define DT_DEBUG_SQLITE3_EXEC(a, b, c, d, e)
#define DT_DEBUG_SQLITE3_PREPARE_V2(a, b, c, d, e)
#define DT_DEBUG_SQLITE3_BIND_INT(a, b, c)
gboolean dt_imageio_lookup_makermodel(const char *maker, const char *model, char *mk, int mk_len, char *md, int md_len, char *al, int al_len)
static const dt_iop_order_entry_t * orders[5]
const char * dt_iop_order_string(const dt_iop_order_t order)
Return the human-readable name for an IOP order enum value.
float *const restrict const size_t k
dt_mipmap_buffer_dsc_flags flags
void copy(double *dest, double *source, size_t num_el)
Copy a flat buffer.
void dt_selection_push(dt_selection_t *selection)
int dt_selection_get_length(struct dt_selection_t *selection)
GList * dt_selection_get_list(struct dt_selection_t *selection)
void dt_selection_clear(dt_selection_t *selection)
void dt_selection_select(dt_selection_t *selection, int32_t imgid)
void dt_selection_pop(dt_selection_t *selection)
#define DT_DEBUG_CONTROL_SIGNAL_RAISE(ctlsig, signal,...)
@ DT_SIGNAL_TAG_CHANGED
This signal is raised when a tag is added/deleted/changed
@ DT_SIGNAL_COLLECTION_CHANGED
This signal is raised when collection changed. To avoid leaking the list, dt_collection_t is connecte...
struct dt_gui_gtk_t * gui
struct dt_collection_t * collection
struct dt_selection_t * selection
const struct dt_database_t * db
struct dt_control_signal_t * signals
struct dt_view_manager_t * view_manager
struct dt_control_t * control
dt_collection_query_flags_t query_flags
dt_collection_sort_t sort
dt_collection_filter_flag_t filter_flags
dt_collection_params_t params
gboolean dt_util_dir_exist(const char *dir)
GList * dt_util_str_to_glist(const gchar *separator, const gchar *text)
gchar * dt_util_glist_to_str(const gchar *separator, GList *items)
gchar * dt_util_dstrcat(gchar *str, const gchar *format,...)
const dt_view_t * dt_view_manager_get_current_view(dt_view_manager_t *vm)