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);
1197 char *escaped_text = sqlite3_mprintf(
"%q", text);
1198 const unsigned int escaped_length = strlen(escaped_text);
1199 gchar *query = NULL;
1208 query = g_strdup_printf(
"(%s)", text);
1210 query = g_strdup(
"1=1");
1214 if(!(escaped_text && *escaped_text))
1216 query = g_strdup_printf(
"(film_id IN (SELECT id FROM main.film_rolls WHERE folder LIKE '%s%%'))",
1221 query = g_strdup_printf(
"(film_id IN (SELECT id FROM main.film_rolls WHERE folder LIKE '%s'))",
1229 if ((escaped_length > 0) && (escaped_text[escaped_length-1] ==
'*'))
1231 escaped_text[escaped_length-1] =
'\0';
1233 query = g_strdup_printf(
"(film_id IN (SELECT id FROM main.film_rolls WHERE folder LIKE '%s' OR folder LIKE '%s"
1234 G_DIR_SEPARATOR_S
"%%'))",
1235 escaped_text, escaped_text);
1239 else if ((escaped_length > 1) && (strcmp(escaped_text+escaped_length-2,
"|%") == 0 ))
1241 escaped_text[escaped_length-2] =
'\0';
1243 query = g_strdup_printf(
"(film_id IN (SELECT id FROM main.film_rolls WHERE folder LIKE '%s"
1244 G_DIR_SEPARATOR_S
"%%'))",
1251 query = g_strdup_printf(
"(film_id IN (SELECT id FROM main.film_rolls WHERE folder LIKE '%s'))",
1260 if(!(escaped_text && *escaped_text) || strcmp(escaped_text,
"%") == 0)
1262 query = g_strdup_printf(
"(id IN (SELECT imgid FROM main.color_labels WHERE color IS NOT NULL))");
1267 if(strcmp(escaped_text, _(
"red")) == 0)
1269 else if(strcmp(escaped_text, _(
"yellow")) == 0)
1271 else if(strcmp(escaped_text, _(
"green")) == 0)
1273 else if(strcmp(escaped_text, _(
"blue")) == 0)
1275 else if(strcmp(escaped_text, _(
"purple")) == 0)
1278 query = g_strdup_printf(
"(id IN (SELECT imgid FROM main.color_labels WHERE color=%d))", color);
1286 if(strcmp(escaped_text, _(
"altered")) == 0)
1288 query = g_strdup(
"EXISTS (SELECT 1 FROM main.history h WHERE h.imgid = id)");
1290 else if(strcmp(escaped_text, _(
"unaltered")) == 0)
1292 query = g_strdup(
"NOT EXISTS (SELECT 1 FROM main.history h WHERE h.imgid = id)");
1296 query = g_strdup(
"1");
1303 const gboolean not_tagged = strcmp(escaped_text, _(
"not tagged")) == 0;
1304 const gboolean no_location = strcmp(escaped_text, _(
"tagged")) == 0;
1305 const gboolean all_tagged = strcmp(escaped_text, _(
"tagged*")) == 0;
1306 char *escaped_text2 = g_strstr_len(escaped_text, -1,
"|");
1307 char *name_clause = g_strdup_printf(
"t.name LIKE \'%s\' || \'%s\'",
1310 if (escaped_text2 && (escaped_text2[strlen(escaped_text2)-1] ==
'*'))
1312 escaped_text2[strlen(escaped_text2)-1] =
'\0';
1313 name_clause = g_strdup_printf(
"(t.name LIKE \'%s\' || \'%s\' OR t.name LIKE \'%s\' || \'%s|%%\')",
1317 if(not_tagged || all_tagged)
1319 query = g_strdup_printf(
"(id %s IN (SELECT id AS imgid FROM main.images "
1320 "WHERE (longitude IS NOT NULL AND latitude IS NOT NULL))) ",
1321 all_tagged ?
"" :
"not");
1325 query = g_strdup_printf(
"(id IN (SELECT id AS imgid FROM main.images "
1326 "WHERE (longitude IS NOT NULL AND latitude IS NOT NULL))"
1327 "AND id %s IN (SELECT imgid FROM main.tagged_images AS ti"
1328 " JOIN data.tags AS t"
1329 " ON t.id = ti.tagid"
1331 no_location ?
"not" :
"",
1339 query = g_strdup_printf(
"(id %s IN (SELECT id AS imgid FROM main.images WHERE (flags & %d))) ",
1340 (strcmp(escaped_text, _(
"not copied locally")) == 0) ?
"not" :
"",
1347 query = g_strdup_printf(
"((1=0)");
1348 GList *lists = NULL;
1350 for(GList *element = lists; element; element = g_list_next(element))
1352 GList *tuple = element->data;
1353 char *clause = sqlite3_mprintf(
" OR (maker = '%q' AND model = '%q')", tuple->data, tuple->next->data);
1355 sqlite3_free(clause);
1368 if(!strcmp(escaped_text, _(
"not tagged")))
1371 query = g_strdup_printf(
"(id NOT IN (SELECT DISTINCT imgid FROM main.tagged_images "
1372 "WHERE tagid NOT IN memory.darktable_tags))");
1377 if ((escaped_length > 0) && (escaped_text[escaped_length-1] ==
'*'))
1381 escaped_text[escaped_length-1] =
'\0';
1383 query = g_strdup_printf(
"(id IN (SELECT imgid FROM main.tagged_images WHERE tagid IN "
1384 "(SELECT id FROM data.tags "
1385 "WHERE LOWER(name) = LOWER('%s')"
1386 " OR SUBSTR(LOWER(name), 1, LENGTH('%s') + 1) = LOWER('%s|'))))",
1387 escaped_text, escaped_text, escaped_text);
1390 else if ((escaped_length > 0) && (escaped_text[escaped_length-1] ==
'%'))
1393 escaped_text[escaped_length-1] =
'\0';
1395 query = g_strdup_printf(
"(id IN (SELECT imgid FROM main.tagged_images WHERE tagid IN "
1396 "(SELECT id FROM data.tags WHERE SUBSTR(LOWER(name), 1, LENGTH('%s')) = LOWER('%s'))))",
1397 escaped_text, escaped_text);
1404 query = g_strdup_printf(
"(id IN (SELECT imgid FROM main.tagged_images WHERE tagid IN "
1405 "(SELECT id FROM data.tags WHERE LOWER(name) = LOWER('%s'))))",
1414 query = g_strdup_printf(
"(lens LIKE '%%%s%%')", escaped_text);
1419 gchar *
operator, *number1, *number2;
1422 if(
operator && strcmp(
operator,
"[]") == 0)
1424 if(number1 && number2)
1425 query = g_strdup_printf(
"((focal_length >= %s) AND (focal_length <= %s))", number1, number2);
1427 else if(
operator && number1)
1428 query = g_strdup_printf(
"(focal_length %s %s)",
operator, number1);
1431 query = g_strdup_printf(
"(CAST(focal_length AS INTEGER) = CAST(%s AS INTEGER))", number1);
1434 query = g_strdup_printf(
"(focal_length LIKE '%%%s%%')", escaped_text);
1444 gchar *
operator, *number1, *number2;
1447 if(
operator && strcmp(
operator,
"[]") == 0)
1449 if(number1 && number2)
1450 query = g_strdup_printf(
"((iso >= %s) AND (iso <= %s))", number1, number2);
1452 else if(
operator && number1)
1453 query = g_strdup_printf(
"(iso %s %s)",
operator, number1);
1455 query = g_strdup_printf(
"(iso = %s)", number1);
1457 query = g_strdup_printf(
"(iso LIKE '%%%s%%')", escaped_text);
1467 gchar *
operator, *number1, *number2;
1470 if(
operator && strcmp(
operator,
"[]") == 0)
1472 if(number1 && number2)
1474 query = g_strdup_printf(
"((ROUND(aperture,1) >= %s) AND (ROUND(aperture,1) <= %s))", number1,
1478 else if(
operator && number1)
1479 query = g_strdup_printf(
"(ROUND(aperture,1) %s %s)",
operator, number1);
1481 query = g_strdup_printf(
"(ROUND(aperture,1) = %s)", number1);
1483 query = g_strdup_printf(
"(ROUND(aperture,1) LIKE '%%%s%%')", escaped_text);
1493 gchar *
operator, *number1, *number2;
1496 if(
operator && strcmp(
operator,
"[]") == 0)
1498 if(number1 && number2)
1500 query = g_strdup_printf(
"((exposure >= %s - 1.0/100000) AND (exposure <= %s + 1.0/100000))", number1,
1504 else if(
operator && number1)
1505 query = g_strdup_printf(
"(exposure %s %s)",
operator, number1);
1508 query = g_strdup_printf(
"(CASE WHEN exposure < 0.4 THEN ((exposure >= %s - 1.0/100000) AND (exposure <= %s + 1.0/100000)) "
1509 "ELSE (ROUND(exposure,2) >= %s - 1.0/100000) AND (ROUND(exposure,2) <= %s + 1.0/100000) END)",
1510 number1, number1, number1, number1);
1513 query = g_strdup_printf(
"(exposure LIKE '%%%s%%')", escaped_text);
1525 for (GList *l = list; l; l = g_list_next(l))
1527 char *
name = (
char*)l->data;
1528 l->data = g_strdup_printf(
"(filename LIKE '%%%s%%')",
name);
1533 query = g_strdup_printf(
"(%s)", subquery);
1547 const int local_property = property;
1548 char *colname = NULL;
1550 switch(local_property)
1559 gchar *
operator, *number1, *number2;
1561 if(number1 && number1[strlen(number1) - 1] ==
'%')
1562 number1[strlen(number1) - 1] =
'\0';
1566 if(strcmp(
operator,
"[]") == 0)
1568 if(number1 && number2)
1569 query = g_strdup_printf(
"((%s >= %" G_GINT64_FORMAT
") AND (%s <= %" G_GINT64_FORMAT
"))", colname, nb1, colname, nb2);
1571 else if((strcmp(
operator,
"=") == 0 || strcmp(
operator,
"") == 0) && number1 && number2)
1572 query = g_strdup_printf(
"((%s >= %" G_GINT64_FORMAT
") AND (%s <= %" G_GINT64_FORMAT
"))", colname, nb1, colname, nb2);
1573 else if(strcmp(
operator,
"<>") == 0 && number1 && number2)
1574 query = g_strdup_printf(
"((%s < %" G_GINT64_FORMAT
") AND (%s > %" G_GINT64_FORMAT
"))", colname, nb1, colname, nb2);
1576 query = g_strdup_printf(
"(%s %s %" G_GINT64_FORMAT
")", colname,
operator, nb1);
1578 query = g_strdup(
"1 = 1");
1587 query = g_strdup_printf(
"(id %s group_id)", (strcmp(escaped_text, _(
"group leaders")) == 0) ?
"=" :
"!=");
1593 query = g_strdup_printf(
"(id IN (SELECT imgid AS id FROM main.history AS h "
1594 "JOIN memory.darktable_iop_names AS m ON m.operation = h.operation "
1595 "WHERE h.enabled = 1 AND m.name LIKE '%s'))", escaped_text);
1609 query = g_strdup_printf(
"(id IN (SELECT imgid FROM main.module_order WHERE version = %d))",
i);
1613 query = g_strdup_printf(
"(id NOT IN (SELECT imgid FROM main.module_order))");
1620 gchar *
operator, *number1, *number2;
1623 if(
operator && strcmp(
operator,
"[]") == 0)
1625 if(number1 && number2)
1627 if(atoi(number1) == -1)
1630 query = g_strdup_printf(
"(flags & 7 >= %s AND flags & 7 <= %s)", number1, number2);
1636 query = g_strdup_printf(
"((flags & 8 == 0) AND (flags & 7 >= %s AND flags & 7 <= %s))", number1, number2);
1641 else if(
operator && number1)
1643 if(g_strcmp0(
operator,
"<=") == 0 || g_strcmp0(
operator,
"<") == 0)
1646 query = g_strdup_printf(
"(flags & 8 == 8 OR flags & 7 %s %s)",
operator, number1);
1649 else if(g_strcmp0(
operator,
">=") == 0 || g_strcmp0(
operator,
">") == 0)
1651 if(atoi(number1) >= 0)
1654 query = g_strdup_printf(
"(flags & 8 == 0 AND flags & 7 %s %s)",
operator, number1);
1661 if(atoi(number1) == -1)
1663 query = g_strdup_printf(
"(flags & 8 == 0)");
1667 query = g_strdup_printf(
"(flags & 8 == 8 OR flags & 7 %s %s)",
operator, number1);
1673 if(atoi(number1) == -1)
1675 query = g_strdup_printf(
"(flags & 8 == 8)");
1679 query = g_strdup_printf(
"(flags & 8 == 0 AND flags & 7 == %s)", number1);
1695 if(strcmp(escaped_text, _(
"not defined")) != 0)
1697 query = g_strdup_printf(
"(id IN (SELECT id FROM main.meta_data WHERE key = %d AND value "
1698 "LIKE '%%%s%%'))", keyid, escaped_text);
1702 query = g_strdup_printf(
"(id NOT IN (SELECT id FROM main.meta_data WHERE key = %d))",
1709 sqlite3_free(escaped_text);
1712 query = g_strdup_printf(
"(1=1)");
1722 GList *result = NULL;
1726 gchar *query = g_strdup_printf(
"SELECT id FROM main.images WHERE %s", where);
1729 sqlite3_stmt *stmt = NULL;
1733 while(sqlite3_step(stmt) == SQLITE_ROW)
1734 result = g_list_prepend(result, GINT_TO_POINTER(sqlite3_column_int(stmt, 0)));
1735 sqlite3_finalize(stmt);
1739 return g_list_reverse(result);
1768 gchar *q = g_strdup_printf(
"SELECT maker, model, COUNT(*) AS count FROM main.images AS mi"
1769 " WHERE %s GROUP BY maker, model", where_ext);
1771 sqlite3_stmt *stmt = NULL;
1774 while(stmt && sqlite3_step(stmt) == SQLITE_ROW)
1776 const char *
maker = (
const char *)sqlite3_column_text(stmt, 0);
1777 const char *
model = (
const char *)sqlite3_column_text(stmt, 1);
1781 if(stmt) sqlite3_finalize(stmt);
1783 return g_list_reverse(
out);
1791 const gboolean has_status
1793 gchar *query = NULL;
1798 query = g_strdup_printf(
"SELECT folder, film_rolls_id, COUNT(*) AS count, status"
1799 " FROM main.images AS mi"
1800 " JOIN (SELECT fr.id AS film_rolls_id, folder, status"
1801 " FROM main.film_rolls AS fr"
1802 " JOIN memory.film_folder AS ff ON fr.id = ff.id)"
1803 " ON film_id = film_rolls_id"
1804 " WHERE %s GROUP BY folder, film_rolls_id", where_ext);
1808 query = g_strdup_printf(
"SELECT name, 1 AS tagid, SUM(count) AS count"
1809 " FROM (SELECT tagid, COUNT(*) as count"
1810 " FROM main.images AS mi JOIN main.tagged_images ON id = imgid"
1811 " WHERE %s GROUP BY tagid)"
1812 " JOIN (SELECT LOWER(name) AS name, id AS tag_id FROM data.tags)"
1813 " ON tagid = tag_id GROUP BY name", where_ext);
1815 "SELECT '%s' AS name, 0 as id, COUNT(*) AS count "
1816 "FROM main.images AS mi WHERE mi.id NOT IN"
1817 " (SELECT DISTINCT imgid FROM main.tagged_images AS ti"
1818 " WHERE ti.tagid NOT IN memory.darktable_tags)",
1823 query = g_strdup_printf(
"SELECT CASE WHEN mi.longitude IS NULL OR mi.latitude IS null THEN '%s'"
1824 " ELSE CASE WHEN ta.imgid IS NULL THEN '%s' ELSE '%s' || ta.tagname END"
1825 " END AS name, ta.tagid AS tag_id, COUNT(*) AS count"
1826 " FROM main.images AS mi"
1827 " LEFT JOIN (SELECT imgid, t.id AS tagid, SUBSTR(t.name, %d) AS tagname"
1828 " FROM main.tagged_images AS ti JOIN data.tags AS t ON ti.tagid = t.id"
1829 " JOIN data.locations AS l ON l.tagid = t.id) AS ta ON ta.imgid = mi.id"
1830 " WHERE %s GROUP BY name, tag_id",
1831 _(
"not tagged"), _(
"tagged"), _(
"tagged"),
1836 query = g_strdup_printf(
"SELECT (datetime_taken / 86400000000) * 86400000000 AS date, 1, COUNT(*) AS count"
1837 " FROM main.images AS mi"
1838 " WHERE datetime_taken IS NOT NULL AND datetime_taken <> 0 AND %s"
1839 " GROUP BY date", where_ext);
1848 char *colname = NULL;
1858 query = g_strdup_printf(
"SELECT %s AS date, 1, COUNT(*) AS count FROM main.images AS mi"
1859 " WHERE %s IS NOT NULL AND %s <> 0 AND %s GROUP BY date",
1860 colname, colname, colname, where_ext);
1865 query = g_strdup_printf(
"SELECT CASE WHEN EXISTS (SELECT 1 FROM main.history h WHERE h.imgid = mi.id)"
1866 " THEN '%s' ELSE '%s' END as altered, 1, COUNT(*) AS count"
1867 " FROM main.images AS mi WHERE %s GROUP BY altered ORDER BY altered ASC",
1868 _(
"altered"), _(
"unaltered"), where_ext);
1872 query = g_strdup_printf(
"SELECT CASE WHEN (flags & %d) THEN '%s' ELSE '%s' END as lcp, 1, COUNT(*) AS count"
1873 " FROM main.images AS mi WHERE %s GROUP BY lcp ORDER BY lcp ASC",
1878 query = g_strdup_printf(
"SELECT CASE color WHEN 0 THEN '%s' WHEN 1 THEN '%s' WHEN 2 THEN '%s'"
1879 " WHEN 3 THEN '%s' WHEN 4 THEN '%s' ELSE '' END, color, COUNT(*) AS count"
1880 " FROM main.images AS mi"
1881 " JOIN (SELECT imgid AS color_labels_id, color FROM main.color_labels)"
1882 " ON id = color_labels_id WHERE %s GROUP BY color ORDER BY color DESC",
1883 _(
"red"), _(
"yellow"), _(
"green"), _(
"blue"), _(
"purple"), where_ext);
1887 query = g_strdup_printf(
"SELECT lens, 1, COUNT(*) AS count FROM main.images AS mi WHERE %s"
1888 " GROUP BY lens ORDER BY lens", where_ext);
1892 query = g_strdup_printf(
"SELECT CAST(focal_length AS INTEGER) AS focal_length, 1, COUNT(*) AS count"
1893 " FROM main.images AS mi WHERE %s GROUP BY CAST(focal_length AS INTEGER)"
1894 " ORDER BY CAST(focal_length AS INTEGER)", where_ext);
1898 query = g_strdup_printf(
"SELECT CAST(iso AS INTEGER) AS iso, 1, COUNT(*) AS count"
1899 " FROM main.images AS mi WHERE %s GROUP BY iso ORDER BY iso", where_ext);
1903 query = g_strdup_printf(
"SELECT ROUND(aperture,1) AS aperture, 1, COUNT(*) AS count"
1904 " FROM main.images AS mi WHERE %s GROUP BY aperture ORDER BY aperture", where_ext);
1908 query = g_strdup_printf(
"SELECT CASE WHEN (exposure < 0.4) THEN '1/' || CAST(1/exposure + 0.9 AS INTEGER)"
1909 " ELSE ROUND(exposure,2) || '\"' END as _exposure, 1, COUNT(*) AS count"
1910 " FROM main.images AS mi WHERE %s GROUP BY _exposure ORDER BY exposure", where_ext);
1914 query = g_strdup_printf(
"SELECT filename, 1, COUNT(*) AS count FROM main.images AS mi WHERE %s"
1915 " GROUP BY filename ORDER BY filename", where_ext);
1919 query = g_strdup_printf(
"SELECT CASE WHEN id = group_id THEN '%s' ELSE '%s' END as group_leader, 1,"
1920 " COUNT(*) AS count FROM main.images AS mi WHERE %s"
1921 " GROUP BY group_leader ORDER BY group_leader ASC",
1922 _(
"group leaders"), _(
"group followers"), where_ext);
1926 query = g_strdup_printf(
"SELECT m.name AS module_name, 1, COUNT(*) AS count FROM main.images AS mi"
1927 " JOIN (SELECT DISTINCT imgid, operation FROM main.history WHERE enabled = 1) AS h"
1928 " ON h.imgid = mi.id JOIN memory.darktable_iop_names AS m"
1929 " ON m.operation = h.operation WHERE %s GROUP BY module_name ORDER BY module_name",
1939 query = g_strdup_printf(
"SELECT CASE %s END as ver, 1, COUNT(*) AS count FROM main.images AS mi"
1940 " LEFT JOIN (SELECT imgid, version FROM main.module_order) mo ON mo.imgid = mi.id"
1941 " WHERE %s GROUP BY ver ORDER BY ver",
orders, where_ext);
1947 query = g_strdup_printf(
"SELECT CASE WHEN (flags & 8) == 8 THEN -1 ELSE (flags & 7) END AS rating, 1,"
1948 " COUNT(*) AS count FROM main.images AS mi WHERE %s GROUP BY rating ORDER BY rating",
1957 char *setting = g_strdup_printf(
"plugins/lighttable/metadata/%s_flag",
name);
1961 query = g_strdup_printf(
"SELECT CASE WHEN value IS NULL THEN '%s' ELSE value END AS value, 1,"
1962 " COUNT(*) AS count, CASE WHEN value IS NULL THEN 0 ELSE 1 END AS force_order"
1963 " FROM main.images AS mi"
1964 " LEFT JOIN (SELECT id AS meta_data_id, value FROM main.meta_data WHERE key = %d)"
1965 " ON id = meta_data_id WHERE %s GROUP BY value ORDER BY force_order, value",
1966 _(
"not defined"), keyid, where_ext);
1970 gchar *order_by = NULL;
1972 if(strcmp(filmroll_sort,
"id") == 0)
1973 order_by = g_strdup(
"film_rolls_id DESC");
1975 order_by =
dt_conf_get_bool(
"plugins/collect/descending") ? g_strdup(
"folder DESC") : g_strdup(
"folder");
1976 query = g_strdup_printf(
"SELECT folder, film_rolls_id, COUNT(*) AS count, status FROM main.images AS mi"
1977 " JOIN (SELECT fr.id AS film_rolls_id, folder, status FROM main.film_rolls AS fr"
1978 " JOIN memory.film_folder AS ff ON ff.id = fr.id) ON film_id = film_rolls_id"
1979 " WHERE %s GROUP BY folder ORDER BY %s", where_ext, order_by);
1985 if(!query)
return NULL;
1987 sqlite3_stmt *stmt = NULL;
1989 while(stmt && sqlite3_step(stmt) == SQLITE_ROW)
1997 name = g_strdup(sdt);
2001 const char *txt = (
const char *)sqlite3_column_text(stmt, 0);
2002 name = txt ? g_strdup(txt) : g_strdup(
"");
2004 const int id = sqlite3_column_int(stmt, 1);
2005 const int count = sqlite3_column_int(stmt, 2);
2006 const int status = has_status ? sqlite3_column_int(stmt, 3) : -1;
2009 if(stmt) sqlite3_finalize(stmt);
2011 return g_list_reverse(
out);
2018 const int num_rules =
dt_conf_get_int(
"plugins/lighttable/collect/num_rules");
2019 c = snprintf(buf, bufsize,
"%d:", num_rules);
2022 for(
int k = 0;
k < num_rules;
k++)
2024 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/mode%1d",
k);
2026 c = snprintf(buf, bufsize,
"%d:", mode);
2029 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/item%1d",
k);
2031 c = snprintf(buf, bufsize,
"%d:", item);
2034 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/string%1d",
k);
2036 if(str && (str[0] !=
'\0'))
2037 c = snprintf(buf, bufsize,
"%s$", str);
2039 c = snprintf(buf, bufsize,
"%%$");
2049 sscanf(buf,
"%d", &num_rules);
2059 int mode = 0, item = 0;
2061 while(buf[0] !=
'\0' && buf[0] !=
':') buf++;
2062 if(buf[0] ==
':') buf++;
2063 char str[400], confname[200];
2064 for(
int k = 0;
k < num_rules;
k++)
2066 const int n = sscanf(buf,
"%d:%d:%399[^$]", &mode, &item, str);
2069 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/mode%1d",
k);
2071 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/item%1d",
k);
2073 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/string%1d",
k);
2076 else if(num_rules == 1)
2078 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/mode%1d",
k);
2080 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/item%1d",
k);
2082 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/string%1d",
k);
2091 while(buf[0] !=
'$' && buf[0] !=
'\0') buf++;
2092 if(buf[0] ==
'$') buf++;
2105 char confname[200] = { 0 };
2110 gboolean found_duplicate =
FALSE;
2113 int num_items =
dt_conf_get_int(
"plugins/lighttable/recentcollect/num_items");
2114 for(
int k = 0;
k < num_items;
k++)
2116 snprintf(confname,
sizeof(confname),
"plugins/lighttable/recentcollect/line%1d",
k);
2119 if(!strcmp(line, buf))
2122 found_duplicate =
TRUE;
2130 const int max_items = CLAMP(
dt_conf_get_int(
"plugins/lighttable/recentcollect/max_items"), 1,
2132 int shifted_index =
MIN(num_items - (found_duplicate ? 1 : 0), max_items);
2133 for(
int k = num_items - 1;
k > -1;
k--)
2135 if(
k ==
n)
continue;
2138 snprintf(confname,
sizeof(confname),
"plugins/lighttable/recentcollect/line%1d",
k);
2140 snprintf(confname,
sizeof(confname),
"plugins/lighttable/recentcollect/pos%1d",
k);
2150 if(shifted_index >= 0 && shifted_index < max_items)
2152 snprintf(confname,
sizeof(confname),
"plugins/lighttable/recentcollect/line%1d", shifted_index);
2154 snprintf(confname,
sizeof(confname),
"plugins/lighttable/recentcollect/pos%1d", shifted_index);
2165 num_items += found_duplicate ? 0 : 1;
2166 dt_conf_set_int(
"plugins/lighttable/recentcollect/num_items", CLAMP(num_items, 1, max_items));
2182 for(GList *l = list; l; l = g_list_next(l))
2184 const int id = GPOINTER_TO_INT(l->data);
2194 gchar *query = g_strdup_printf(
"SELECT imgid"
2195 " FROM memory.collected_images"
2196 " WHERE imgid NOT IN (%s)"
2197 " AND rowid > (SELECT rowid"
2198 " FROM memory.collected_images"
2199 " WHERE imgid IN (%s)"
2200 " ORDER BY rowid LIMIT 1)"
2201 " ORDER BY rowid LIMIT 1",
2204 sqlite3_stmt *stmt2;
2206 if(sqlite3_step(stmt2) == SQLITE_ROW)
2208 next = sqlite3_column_int(stmt2, 0);
2210 sqlite3_finalize(stmt2);
2216 query = g_strdup_printf(
"SELECT imgid"
2217 " FROM memory.collected_images"
2218 " WHERE imgid NOT IN (%s)"
2219 " AND rowid < (SELECT rowid"
2220 " FROM memory.collected_images"
2221 " WHERE imgid IN (%s)"
2222 " ORDER BY rowid LIMIT 1)"
2223 " ORDER BY rowid DESC LIMIT 1",
2227 if(sqlite3_step(stmt2) == SQLITE_ROW)
2229 next = sqlite3_column_int(stmt2, 0);
2231 sqlite3_finalize(stmt2);
2239 const int _n_r =
dt_conf_get_int(
"plugins/lighttable/collect/num_rules");
2240 const int num_rules = CLAMP(_n_r, 1, 10);
2241 char *conj[] = {
"AND",
"OR",
"AND NOT" };
2243 gchar **query_parts = g_new (gchar*, num_rules + 1);
2244 query_parts[num_rules] = NULL;
2246 for(
int i = 0;
i < num_rules;
i++)
2248 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/item%1d",
i);
2250 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/string%1d",
i);
2252 snprintf(confname,
sizeof(confname),
"plugins/lighttable/collect/mode%1d",
i);
2258 query_parts[
i] = g_strdup(
" OR 1=1");
2260 query_parts[
i] = g_strdup(
"");
2266 query_parts[
i] = g_strdup_printf(
" %s %s", conj[mode], query);
2275 g_strfreev(query_parts);
2297 "INSERT INTO memory.collected_images"
2298 " SELECT * FROM memory.collected_backup",
2307 "INSERT INTO memory.collected_backup"
2308 " SELECT * FROM memory.collected_images",
2319 "DELETE FROM memory.collected_images"
2320 " WHERE imgid NOT IN "
2321 " (SELECT imgid FROM main.selected_images)",
2360 selected = GPOINTER_TO_INT(selected_imgids->data);
2364 g_list_free(selected_imgids);
2365 selected_imgids = NULL;
2366 message = g_strdup_printf(_(
"%d image of %d (#%d) in current collection is selected"), cs, c, selected);
2370 message = g_strdup_printf(
2372 "%d image of %d in current collection is selected",
2373 "%d images of %d in current collection are selected",
2388 "SELECT imgid FROM memory.collected_images",
2392 sqlite3_reset(stmt);
2393 sqlite3_clear_bindings(stmt);
2395 gboolean found =
FALSE;
2397 while(sqlite3_step(stmt) == SQLITE_ROW)
2399 const int id = sqlite3_column_int(stmt, 0);
2408 if(!found) offset = 0;
2415 if(open_single_image)
2417 if(!g_strcmp0(current_view->
module_name,
"darkroom"))
2422 else if(g_strcmp0(current_view->
module_name,
"lighttable"))
2432 result |= current_atelier && g_strcmp0(current_atelier->
module_name,
"lighttable");
2448 gchar first_directory[
PATH_MAX] = { 0 };
2471 fprintf(stdout,
"Collection: one folder.\n");
2472 g_strlcpy(dir, g_strdup(first_selection),
sizeof(dir));
2476 fprintf(stdout,
"Collection: files and folders.\n");
2479 g_strlcpy(dir, g_strdup(import_last_dir),
sizeof(dir));
2484 fprintf(stdout,
"Collection: copy or in List view.\n");
2486 gchar first_img_path[
PATH_MAX] = { 0 };
2491 g_strlcpy(dir, first_img_path,
sizeof(dir));
2492 fprintf(stdout,
"Collection: ID %d, last img path %s.\n", imgid, first_img_path);
2496 fprintf(stdout,
"Collection: view = %s\n", Collection_view ?
"Tree" :
"List");
2497 const char *path = g_strdup_printf(
"%s%s", dir, Collection_view ?
"*" :
"");
2498 fprintf(stdout,
"Collection: path = %s\n", path);
2500 dt_conf_set_string(
"plugins/lighttable/collect/string0", g_strdup_printf(
"%s*", dir));
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)
GList * dt_collection_get_images_for_rule(const dt_collection_properties_t property, const char *text)
const gchar * dt_collection_get_query(const dt_collection_t *collection)
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)
static gchar * get_query_string(const dt_collection_properties_t property, const gchar *text)
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)
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)