Example #1
0
void dt_selection_deselect(dt_selection_t *selection, uint32_t imgid)
{
  gchar *query = NULL;
  selection->last_single_id = -1;

  if(imgid != -1)
  {
    const dt_image_t *image = dt_image_cache_get(darktable.image_cache, imgid, 'r');
    if(image)
    {
      int img_group_id = image->group_id;
      dt_image_cache_read_release(darktable.image_cache, image);

      if(!darktable.gui || !darktable.gui->grouping || darktable.gui->expanded_group_id == img_group_id)
      {
        query = dt_util_dstrcat(query, "DELETE FROM main.selected_images WHERE imgid = %d", imgid);
      }
      else
      {
        query = dt_util_dstrcat(query, "DELETE FROM main.selected_images WHERE imgid IN "
                                       "(SELECT id FROM main.images WHERE group_id = %d)",
                                img_group_id);
      }

      DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), query, NULL, NULL, NULL);
      g_free(query);
    }
  }

  /* update hint message */
  dt_collection_hint_message(darktable.collection);
}
Example #2
0
void dt_selection_invert(dt_selection_t *selection)
{
  gchar *fullq = NULL;

  if (!selection->collection)
    return;

  fullq = dt_util_dstrcat(fullq, "%s", "insert or ignore into selected_images ");
  fullq = dt_util_dstrcat(fullq, "%s", dt_collection_get_query(selection->collection));

  DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db),
                        "insert into memory.tmp_selection select imgid from selected_images",
                        NULL, NULL, NULL);
  DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db),
                        "delete from selected_images",
                        NULL, NULL, NULL);
  DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), fullq,
                        NULL, NULL, NULL);
  DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db),
                        "delete from selected_images where imgid in (select imgid from memory.tmp_selection)",
                        NULL, NULL, NULL);
  DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db),
                        "delete from memory.tmp_selection",
                        NULL, NULL, NULL);

  g_free(fullq);

  /* update hint message */
  dt_collection_hint_message(darktable.collection);
}
Example #3
0
void dt_selection_invert(dt_selection_t *selection)
{
  gchar *fullq = NULL;

  if(!selection->collection) return;

  fullq = dt_util_dstrcat(fullq, "%s", "INSERT OR IGNORE INTO main.selected_images ");
  fullq = dt_util_dstrcat(fullq, "%s", dt_collection_get_query(selection->collection));

  DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db),
                        "INSERT INTO memory.tmp_selection SELECT imgid FROM main.selected_images", NULL, NULL,
                        NULL);
  DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), "DELETE FROM main.selected_images", NULL, NULL, NULL);
  DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), fullq, NULL, NULL, NULL);
  DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db),
                        "DELETE FROM main.selected_images WHERE imgid IN (SELECT imgid FROM memory.tmp_selection)",
                        NULL, NULL, NULL);
  DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), "DELETE FROM memory.tmp_selection", NULL, NULL, NULL);

  g_free(fullq);

  dt_control_signal_raise(darktable.signals, DT_SIGNAL_SELECTION_CHANGED);

  /* update hint message */
  dt_collection_hint_message(darktable.collection);
}
Example #4
0
void dt_selection_select_list(struct dt_selection_t *selection, GList *list)
{
  if(!list) return;
  while(list)
  {
    int count = 1;
    gchar *query = NULL;

    int imgid = GPOINTER_TO_INT(list->data);
    selection->last_single_id = imgid;
    query = dt_util_dstrcat(query, "INSERT OR IGNORE INTO main.selected_images VALUES (%d)", imgid);
    list = g_list_next(list);
    while(list && count < 400)
    {
      imgid = GPOINTER_TO_INT(list->data);
      count++;
      selection->last_single_id = imgid;
      query = dt_util_dstrcat(query, ",(%d)", imgid);
      list = g_list_next(list);
    }
    char *result = NULL;

    sqlite3_exec(dt_database_get(darktable.db), query, NULL, NULL, &result);

    g_free(query);
  }

  /* update hint message */
  dt_collection_hint_message(darktable.collection);
}
Example #5
0
void dt_selection_select(dt_selection_t *selection, uint32_t imgid)
{
  gchar *query = NULL;

  if(imgid != -1)
  {
    const dt_image_t *image = dt_image_cache_get(darktable.image_cache, imgid, 'r');
    if(image)
    {
      int img_group_id = image->group_id;
      dt_image_cache_read_release(darktable.image_cache, image);

      if(!darktable.gui || !darktable.gui->grouping || darktable.gui->expanded_group_id == img_group_id || !selection->collection)
      {
        query = dt_util_dstrcat(query, "INSERT OR IGNORE INTO main.selected_images VALUES (%d)", imgid);
      }
      else
      {
        query = dt_util_dstrcat(query, "INSERT OR IGNORE INTO main.selected_images SELECT id FROM main.images "
                                       "WHERE group_id = %d AND id IN (%s)",
                                img_group_id, dt_collection_get_query_no_group(selection->collection));
      }

      DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), query, NULL, NULL, NULL);
      g_free(query);
    }
  }

  /* update hint message */
  dt_collection_hint_message(darktable.collection);
}
Example #6
0
static gboolean _lib_filmstrip_imgid_in_collection(const dt_collection_t *collection, const int imgid)
{
  sqlite3_stmt *stmt = NULL;
  uint32_t count=1;
  const gchar *query = dt_collection_get_query(collection);
  gchar *count_query = NULL;

  //gchar *fq = g_strstr_len(query, strlen(query), "from");
  gchar *fw = g_strstr_len(query, strlen(query), "where") + 6;

  gchar *qq = NULL;
  qq = dt_util_dstrcat(qq, "id=?3 and %s", fw);

  if ((collection->params.query_flags&COLLECTION_QUERY_USE_ONLY_WHERE_EXT))
    count_query = dt_util_dstrcat(NULL, "select count(images.id) from images %s and id=?3", collection->where_ext);
  else
    count_query = dt_util_dstrcat(count_query, "select count(id) from images where %s", qq);

  DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), count_query, -1, &stmt, NULL);
  if ((collection->params.query_flags&COLLECTION_QUERY_USE_LIMIT) &&
      !(collection->params.query_flags&COLLECTION_QUERY_USE_ONLY_WHERE_EXT))
  {
    DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, 0);
    DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, -1);
  }
  DT_DEBUG_SQLITE3_BIND_INT(stmt, 3, imgid);

  if(sqlite3_step(stmt) == SQLITE_ROW)
    count = sqlite3_column_int(stmt, 0);
  sqlite3_finalize(stmt);
  g_free(count_query);
  return count;
}
Example #7
0
static uint32_t _dt_collection_compute_count(const dt_collection_t *collection)
{
  sqlite3_stmt *stmt = NULL;
  uint32_t count=1;
  const gchar *query = dt_collection_get_query(collection);
  gchar *count_query = NULL;

  gchar *fq = g_strstr_len(query, strlen(query), "from");
  if ((collection->params.query_flags&COLLECTION_QUERY_USE_ONLY_WHERE_EXT))
    count_query = dt_util_dstrcat(NULL, "select count(images.id) from images %s", collection->where_ext);
  else
    count_query = dt_util_dstrcat(count_query, "select count(id) %s", fq);

  DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), count_query, -1, &stmt, NULL);
  if ((collection->params.query_flags&COLLECTION_QUERY_USE_LIMIT) &&
      !(collection->params.query_flags&COLLECTION_QUERY_USE_ONLY_WHERE_EXT))
  {
    DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, 0);
    DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, -1);
  }

  if(sqlite3_step(stmt) == SQLITE_ROW)
    count = sqlite3_column_int(stmt, 0);
  sqlite3_finalize(stmt);
  g_free(count_query);
  return count;
}
Example #8
0
void dt_selection_select_unaltered(dt_selection_t *selection)
{
  char *fullq = NULL;

  if (!selection->collection)
    return;

  /* set unaltered collection filter and update query */
  uint32_t old_filter_flags = dt_collection_get_filter_flags(selection->collection);
  dt_collection_set_filter_flags (selection->collection,
                                  (dt_collection_get_filter_flags(selection->collection) |
                                   COLLECTION_FILTER_UNALTERED));
  dt_collection_update(selection->collection);


  fullq = dt_util_dstrcat(fullq, "%s", "insert or ignore into selected_images ");
  fullq = dt_util_dstrcat(fullq, "%s", dt_collection_get_query(selection->collection));


  /* clean current selection and select unaltered images */
  DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db),
                        "delete from selected_images", NULL, NULL, NULL);
  DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db),
                        fullq, NULL, NULL, NULL);

  /* restore collection filter and update query */
  dt_collection_set_filter_flags(selection->collection, old_filter_flags);
  dt_collection_update(selection->collection);

  g_free(fullq);

  selection->last_single_id = -1;
}
Example #9
0
void dt_selection_toggle(dt_selection_t *selection, uint32_t imgid)
{
  gchar *query = NULL;
  sqlite3_stmt *stmt;
  gboolean exists = FALSE;

  DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db),
                              "select imgid from selected_images where imgid=?1",-1,&stmt,NULL);
  DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid);

  if(sqlite3_step(stmt) == SQLITE_ROW)
    exists = TRUE;

  sqlite3_finalize(stmt);

  if (exists)
  {
    selection->last_single_id = -1;
    query = dt_util_dstrcat(query,"delete from selected_images where imgid = %d", imgid);
  }
  else
  {
    selection->last_single_id = imgid;
    query = dt_util_dstrcat(query,"insert or ignore into selected_images values(%d)", imgid);
  }

  sqlite3_exec(dt_database_get(darktable.db), query, NULL, NULL, NULL);

  g_free(query);

  /* update hint message */
  dt_collection_hint_message(darktable.collection);
}
Example #10
0
void dt_selection_select_range(dt_selection_t *selection, uint32_t imgid)
{
  gchar *fullq = NULL;
  sqlite3_stmt *stmt;
  if (!selection->collection || selection->last_single_id == -1)
    return;

  /* get start and end rows for range selection */
  int rc=0;
  uint32_t sr=-1,er=-1;
  DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db),
                              dt_collection_get_query(selection->collection), -1, &stmt, NULL);

  while(sqlite3_step(stmt)==SQLITE_ROW)
  {
    int id = sqlite3_column_int(stmt, 0);
    if (id == selection->last_single_id)
      sr = rc;

    if (id == imgid)
      er = rc;

    if (sr != -1 && er != -1 )
      break;

    rc++;
  }

  sqlite3_finalize(stmt);

  /* selece the images in range from start to end */
  uint32_t old_flags = dt_collection_get_query_flags(selection->collection);

  /* use the limit to select range of images */
  dt_collection_set_query_flags(selection->collection,
                                (old_flags |COLLECTION_QUERY_USE_LIMIT));

  dt_collection_update(selection->collection);

  fullq = dt_util_dstrcat(fullq, "%s", "insert or ignore into selected_images ");
  fullq = dt_util_dstrcat(fullq, "%s", dt_collection_get_query(selection->collection));

  DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db),
                              fullq, -1, &stmt, NULL);

  DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, MIN(sr,er));
  DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, (MAX(sr,er)-MIN(sr,er))+1);

  sqlite3_step(stmt);

  /* reset filter */
  dt_collection_set_query_flags(selection->collection,
                                old_flags);
  dt_collection_update(selection->collection);
  selection->last_single_id = -1;
}
Example #11
0
void dt_selection_select_range(dt_selection_t *selection, uint32_t imgid)
{
  gchar *fullq = NULL;

  if(!selection->collection || selection->last_single_id == -1) return;

  /* get start and end rows for range selection */
  sqlite3_stmt *stmt;
  int rc = 0;
  uint32_t sr = -1, er = -1;
  DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), dt_collection_get_query_no_group(selection->collection),
                              -1, &stmt, NULL);

  while(sqlite3_step(stmt) == SQLITE_ROW)
  {
    const int id = sqlite3_column_int(stmt, 0);
    if(id == selection->last_single_id) sr = rc;

    if(id == imgid) er = rc;

    if(sr != -1 && er != -1) break;

    rc++;
  }

  sqlite3_finalize(stmt);

  /* select the images in range from start to end */
  const uint32_t old_flags = dt_collection_get_query_flags(selection->collection);

  /* use the limit to select range of images */
  dt_collection_set_query_flags(selection->collection, (old_flags | COLLECTION_QUERY_USE_LIMIT));

  dt_collection_update(selection->collection);

  fullq = dt_util_dstrcat(fullq, "%s", "INSERT OR IGNORE INTO main.selected_images ");
  fullq = dt_util_dstrcat(fullq, "%s", dt_collection_get_query_no_group(selection->collection));

  DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), fullq, -1, &stmt, NULL);

  DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, MIN(sr, er));
  DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, (MAX(sr, er) - MIN(sr, er)) + 1);

  sqlite3_step(stmt);
  sqlite3_finalize(stmt);

  /* reset filter */
  dt_collection_set_query_flags(selection->collection, old_flags);
  dt_collection_update(selection->collection);

  // The logic above doesn't handle groups, so explicitly select the beginning and end to make sure those are selected properly
  dt_selection_select(selection, selection->last_single_id);
  dt_selection_select(selection, imgid);

  g_free(fullq);
}
Example #12
0
gchar *
dt_collection_get_sort_query(const dt_collection_t *collection)
{
  gchar *sq = NULL;

  switch(collection->params.sort)
  {
    case DT_COLLECTION_SORT_DATETIME:
      sq = dt_util_dstrcat(sq, ORDER_BY_QUERY, "datetime_taken");
      break;

    case DT_COLLECTION_SORT_RATING:
      sq = dt_util_dstrcat(sq, ORDER_BY_QUERY, "flags & 7 desc");
      break;

    case DT_COLLECTION_SORT_FILENAME:
      sq = dt_util_dstrcat(sq, ORDER_BY_QUERY, "filename");
      break;

    case DT_COLLECTION_SORT_ID:
      sq = dt_util_dstrcat(sq, ORDER_BY_QUERY, "id");
      break;

    case DT_COLLECTION_SORT_COLOR:
      sq = dt_util_dstrcat(sq, ORDER_BY_QUERY, "color desc, filename");
      break;
  }

  if (collection->params.descending)
  {
    switch(collection->params.sort)
    {
      case DT_COLLECTION_SORT_DATETIME:
      case DT_COLLECTION_SORT_FILENAME:
      case DT_COLLECTION_SORT_ID:
      {
        sq = dt_util_dstrcat(sq, " %s", "desc");
      }
      break;

      /* These two are special as they are descending in the default view */
      case DT_COLLECTION_SORT_RATING:
      {
        g_free(sq);
        sq = NULL;
        sq = dt_util_dstrcat(sq, ORDER_BY_QUERY, "flags & 7");
      }
      break;

      case DT_COLLECTION_SORT_COLOR:
      {
        g_free(sq);
        sq = NULL;
        sq = dt_util_dstrcat(sq, ORDER_BY_QUERY, "color, filename");
      }
      break;
    }
  }
  return sq;
}
Example #13
0
static int collection_numindex(lua_State *L)
{
  int index = luaL_checkinteger(L, -1);
  if(index < 1)
  {
    return luaL_error(L, "incorrect index in database");
  }

  gchar *query = NULL;
  gchar *sq = NULL;

  /* get collection order */
  if((darktable.collection->params.query_flags & COLLECTION_QUERY_USE_SORT))
    sq = dt_collection_get_sort_query(darktable.collection);


  sqlite3_stmt *stmt = NULL;

  /* build the query string */
  query = dt_util_dstrcat(query, "select distinct id from images ");

  if(darktable.collection->params.sort == DT_COLLECTION_SORT_COLOR
     && (darktable.collection->params.query_flags & COLLECTION_QUERY_USE_SORT))
    query = dt_util_dstrcat(query, "as a left outer join color_labels as b on a.id = b.imgid ");

  query = dt_util_dstrcat(query, "%s limit -1 offset ?1", sq);

  DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), query, -1, &stmt, NULL);
  DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, index -1);

  if(sqlite3_step(stmt) == SQLITE_ROW)
  {
    int imgid = sqlite3_column_int(stmt, 0);
    luaA_push(L, dt_lua_image_t, &imgid);
    sqlite3_finalize(stmt);
  }
  else
  {
    g_free(sq);
    g_free(query);
    sqlite3_finalize(stmt);
    return luaL_error(L, "incorrect index in database");
  }
  g_free(sq);
  g_free(query);
  return 1;

}
Example #14
0
/**
 * @see https://developers.google.com/photos/library/guides/create-albums
 * @return the id of the newly reacted
 */
static const gchar *gphoto_create_album(dt_storage_gphoto_gui_data_t *ui, dt_gphoto_context_t *ctx, gchar *name)
{
  struct curl_slist *headers = NULL;

  gchar *jbody = dt_util_dstrcat(NULL, "{ \"album\": { \"title\": \"%s\"} }", name);

  headers = curl_slist_append(headers, "Content-type: application/json");

  JsonObject *response = gphoto_query_post(ctx, GOOGLE_GPHOTO "v1/albums", headers, NULL, jbody, strlen(jbody));

  // add new album into the list
  dt_gphoto_album_t *album = _json_new_album(response);
  GtkListStore *model_album = GTK_LIST_STORE(gtk_combo_box_get_model(ui->combo_album));

  if(album)
  {
    ui_refresh_albums_fill(album, model_album);
    gtk_combo_box_set_active(ui->combo_album, ui->albums_count);
    ui->albums_count++;
    ui_reset_albums_creation(ui);
  }

  g_free(jbody);

  return album?album->id:NULL;
}
Example #15
0
/* splits an input string into a date-time part and an optional operator part.
   operator can be any of "=", "<", ">", "<=", ">=" and "<>".
   range notation [x;y] can also be used
   datetime values should follow the pattern YYYY:mm:dd HH:MM:SS
   but only year part is mandatory

   datetime and operator are returned as pointers to null terminated strings in g_mallocated
   memory (to be g_free'd after use) - or NULL if no match is found.
*/
void dt_collection_split_operator_datetime(const gchar *input, char **number1, char **number2, char **operator)
{
  GRegex *regex;
  GMatchInfo *match_info;
  int match_count;

  *number1 = *number2 = *operator= NULL;

  // we test the range expression first
  // 2 elements : date-time1 and  date-time2
  regex = g_regex_new("^\\s*\\[\\s*(\\d{4}[:\\d\\s]*)\\s*;\\s*(\\d{4}[:\\d\\s]*)\\s*\\]\\s*$", 0, 0, NULL);
  g_regex_match_full(regex, input, -1, 0, 0, &match_info, NULL);
  match_count = g_match_info_get_match_count(match_info);

  if(match_count == 3)
  {
    gchar *txt = g_match_info_fetch(match_info, 1);
    gchar *txt2 = g_match_info_fetch(match_info, 2);

    *number1 = _dt_collection_compute_datetime(">=", txt);
    *number2 = _dt_collection_compute_datetime("<=", txt2);
    *operator= g_strdup("[]");

    g_free(txt);
    g_free(txt2);
    g_match_info_free(match_info);
    g_regex_unref(regex);
    return;
  }

  g_match_info_free(match_info);
  g_regex_unref(regex);

  // and we test the classic comparaison operators
  // 2 elements : operator and date-time
  regex = g_regex_new("^\\s*(=|<|>|<=|>=|<>)?\\s*(\\d{4}[:\\d\\s]*)?\\s*%?\\s*$", 0, 0, NULL);
  g_regex_match_full(regex, input, -1, 0, 0, &match_info, NULL);
  match_count = g_match_info_get_match_count(match_info);

  if(match_count == 3)
  {
    *operator= g_match_info_fetch(match_info, 1);
    gchar *txt = g_match_info_fetch(match_info, 2);

    if(strcmp(*operator, "") == 0 || strcmp(*operator, "=") == 0 || strcmp(*operator, "<>") == 0)
      *number1 = dt_util_dstrcat(*number1, "%s%%", txt);
    else
      *number1 = _dt_collection_compute_datetime(*operator, txt);

    g_free(txt);
  }

  // ensure operator is not null
  if(!*operator) *operator= g_strdup("");

  g_match_info_free(match_info);
  g_regex_unref(regex);
}
Example #16
0
GList *dt_collection_get_selected(const dt_collection_t *collection, int limit)
{
  GList *list = NULL;
  gchar *query = NULL;
  gchar *sq = NULL;

  /* get collection order */
  if((collection->params.query_flags & COLLECTION_QUERY_USE_SORT))
    sq = dt_collection_get_sort_query(collection);


  sqlite3_stmt *stmt = NULL;

  /* build the query string */
  query = dt_util_dstrcat(query, "select distinct id from images ");

  if(collection->params.sort == DT_COLLECTION_SORT_COLOR
     && (collection->params.query_flags & COLLECTION_QUERY_USE_SORT))
    query = dt_util_dstrcat(query, "as a left outer join color_labels as b on a.id = b.imgid ");
  else if(collection->params.sort == DT_COLLECTION_SORT_PATH
          && (collection->params.query_flags & COLLECTION_QUERY_USE_SORT))
    query = dt_util_dstrcat(
        query, "join (select id as film_rolls_id, folder from film_rolls) on film_id = film_rolls_id ");

  query = dt_util_dstrcat(query, "where id in (select imgid from selected_images) %s limit ?1", sq);

  DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), query, -1, &stmt, NULL);
  DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, limit);

  while(sqlite3_step(stmt) == SQLITE_ROW)
  {
    int imgid = sqlite3_column_int(stmt, 0);
    list = g_list_append(list, GINT_TO_POINTER(imgid));
  }

  sqlite3_finalize(stmt);

  /* free allocated strings */
  g_free(sq);

  g_free(query);

  return list;
}
Example #17
0
void dt_selection_select_all(dt_selection_t *selection)
{
  gchar *fullq = NULL;

  if(!selection->collection) return;

  fullq = dt_util_dstrcat(fullq, "%s", "INSERT OR IGNORE INTO main.selected_images ");
  fullq = dt_util_dstrcat(fullq, "%s", dt_collection_get_query_no_group(selection->collection));

  DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), "DELETE FROM main.selected_images", NULL, NULL, NULL);
  DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), fullq, NULL, NULL, NULL);

  selection->last_single_id = -1;

  g_free(fullq);

  /* update hint message */
  dt_collection_hint_message(darktable.collection);
}
Example #18
0
void dt_selection_select_all(dt_selection_t *selection)
{
  gchar *fullq = NULL;

  if (!selection->collection)
    return;

  fullq = dt_util_dstrcat(fullq, "%s", "insert or ignore into selected_images ");
  fullq = dt_util_dstrcat(fullq, "%s", dt_collection_get_query(selection->collection));

  DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), "delete from selected_images", NULL, NULL, NULL);
  DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), fullq, NULL, NULL, NULL);

  selection->last_single_id = -1;

  g_free(fullq);

  /* update hint message */
  dt_collection_hint_message(darktable.collection);
}
Example #19
0
void dt_selection_select_single(dt_selection_t *selection, uint32_t imgid)
{
  gchar *query = NULL;
  selection->last_single_id = imgid;
  DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), "delete from selected_images", NULL, NULL, NULL);
  query = dt_util_dstrcat(query,"insert or ignore into selected_images values(%d)", imgid);
  DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), query, NULL, NULL, NULL);
  g_free(query);

  /* update hint message */
  dt_collection_hint_message(darktable.collection);
}
Example #20
0
GList *dt_collection_get_selected (const dt_collection_t *collection)
{
  GList *list=NULL;
  gchar *query = NULL;
  gchar *sq = NULL;

  /* get collection order */
  if ((collection->params.query_flags&COLLECTION_QUERY_USE_SORT))
    sq = dt_collection_get_sort_query(collection);


  sqlite3_stmt *stmt = NULL;

  /* build the query string */
  query = dt_util_dstrcat(query, "select distinct id from images ");

  if (collection->params.sort == DT_COLLECTION_SORT_COLOR && (collection->params.query_flags & COLLECTION_QUERY_USE_SORT))
    query = dt_util_dstrcat(query, "as a left outer join color_labels as b on a.id = b.imgid ");

  query = dt_util_dstrcat(query, "where id in (select imgid from selected_images) %s", sq);


  DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db),query, -1, &stmt, NULL);

  while (sqlite3_step (stmt) == SQLITE_ROW)
  {
    long int imgid = sqlite3_column_int(stmt, 0);
    list = g_list_append (list, (gpointer)imgid);
  }


  /* free allocated strings */
  if (sq)
    g_free(sq);

  g_free(query);

  return list;
}
Example #21
0
static gchar *gphoto_get_user_refresh_token(dt_gphoto_context_t *ctx)
{
  gchar *refresh_token = NULL;
  JsonObject *reply;
  gchar *params = NULL;

  params = dt_util_dstrcat(params, "refresh_token=%s&client_id=%s&client_secret=%s&grant_type=refresh_token",
                           ctx->refresh_token, ctx->google_client_id, ctx->google_client_secret);

  reply = gphoto_query_post_auth(ctx, GOOGLE_API_BASE_URL "oauth2/v4/token", params);

  refresh_token = g_strdup(json_object_get_string_member(reply, "access_token"));

  g_free(params);

  return refresh_token;
}
Example #22
0
/**
 * perform a POST request on google photo api
 * @returns NULL if the request fails, or a JsonObject of the reply
 */
static JsonObject *gphoto_query_post(dt_gphoto_context_t *ctx, const gchar *url,
                                     struct curl_slist *headers, GList *args, gchar *body, int size)
{
  g_return_val_if_fail(ctx != NULL, NULL);
  g_return_val_if_fail(ctx->token != NULL, NULL);

  // send the request
  GString *response = g_string_new("");

  gchar *auth = dt_util_dstrcat(NULL, "Authorization: Bearer %s", ctx->token);
  struct curl_slist *h = curl_slist_append(headers, auth);

  _buffer_t writebuffer;
  writebuffer.data = (void *)body;
  writebuffer.size = size;
  writebuffer.offset = 0;

  dt_curl_init(ctx->curl_ctx, TRUE);

  curl_easy_setopt(ctx->curl_ctx, CURLOPT_HTTPHEADER, h);

  curl_easy_setopt(ctx->curl_ctx, CURLOPT_URL, url);
  curl_easy_setopt(ctx->curl_ctx, CURLOPT_POST, 1);
  curl_easy_setopt(ctx->curl_ctx, CURLOPT_WRITEFUNCTION, curl_write_data_cb);
  curl_easy_setopt(ctx->curl_ctx, CURLOPT_WRITEDATA, response);
  curl_easy_setopt(ctx->curl_ctx, CURLOPT_READFUNCTION, _gphoto_api_buffer_read_func);
  curl_easy_setopt(ctx->curl_ctx, CURLOPT_READDATA, &writebuffer);

  int res = curl_easy_perform(ctx->curl_ctx);

  curl_slist_free_all(h);
  g_list_free(args);

  if(res != CURLE_OK)
  {
    g_string_free(response, TRUE);
    return NULL;
  }
  // parse the response
  JsonObject *respobj = gphoto_parse_response(ctx, response);

  g_string_free(response, TRUE);

  return respobj;
}
Example #23
0
/**
 * @see https://developers.google.com/accounts/docs/OAuth2InstalledApp#callinganapi
 * @return basic information about the account
 */
static dt_gphoto_account_info_t *gphoto_get_account_info(dt_gphoto_context_t *ctx)
{
  JsonObject *obj = gphoto_query_get(ctx, GOOGLE_API_BASE_URL "oauth2/v1/userinfo", NULL);
  g_return_val_if_fail((obj != NULL), NULL);
  /* Using the email instead of the username as it is unique */
  /* To change it to use the username, change "email" by "name" */
  const gchar *user_name = json_object_get_string_member(obj, "given_name");
  const gchar *email = json_object_get_string_member(obj, "email");
  const gchar *user_id = json_object_get_string_member(obj, "id");
  g_return_val_if_fail(user_name != NULL && user_id != NULL, NULL);

  gchar *name = NULL;
  name = dt_util_dstrcat(name, "%s - %s", user_name, email);

  dt_gphoto_account_info_t *accountinfo = gphoto_account_info_init();
  accountinfo->id = g_strdup(user_id);
  accountinfo->username = g_strdup(name);
  accountinfo->token = g_strdup(ctx->token);
  accountinfo->refresh_token = g_strdup(ctx->refresh_token);

  g_snprintf(ctx->userid, sizeof(ctx->userid), "%s", user_id);
  g_free(name);
  return accountinfo;
}
Example #24
0
void
dt_collection_update_query(const dt_collection_t *collection)
{
  char query[1024], confname[200];
  gchar *complete_query = NULL;

  const int _n_r = dt_conf_get_int("plugins/lighttable/collect/num_rules");
  const int num_rules = CLAMP(_n_r, 1, 10);
  char *conj[] = {"and", "or", "and not"};

  complete_query = dt_util_dstrcat(complete_query, "(");

  for(int i=0; i<num_rules; i++)
  {
    snprintf(confname, sizeof(confname), "plugins/lighttable/collect/item%1d", i);
    const int property = dt_conf_get_int(confname);
    snprintf(confname, sizeof(confname), "plugins/lighttable/collect/string%1d", i);
    gchar *text = dt_conf_get_string(confname);
    if(!text) break;
    snprintf(confname, sizeof(confname), "plugins/lighttable/collect/mode%1d", i);
    const int mode = dt_conf_get_int(confname);
    gchar *escaped_text = dt_util_str_replace(text, "'", "''");

    get_query_string(property, escaped_text, query, sizeof(query));

    if(i > 0)
      complete_query = dt_util_dstrcat(complete_query, " %s %s", conj[mode], query);
    else
      complete_query = dt_util_dstrcat(complete_query, "%s", query);

    g_free(escaped_text);
    g_free(text);
  }

  complete_query = dt_util_dstrcat(complete_query, ")");

  // printf("complete query: `%s'\n", complete_query);

  /* set the extended where and the use of it in the query */
  dt_collection_set_extended_where (collection, complete_query);
  dt_collection_set_query_flags (collection, (dt_collection_get_query_flags (collection) | COLLECTION_QUERY_USE_WHERE_EXT));

  /* remove film id from default filter */
  dt_collection_set_filter_flags (collection, (dt_collection_get_filter_flags (collection) & ~COLLECTION_FILTER_FILM_ID));

  /* update query and at last the visual */
  dt_collection_update (collection);

  /* free string */
  g_free(complete_query);

  // remove from selected images where not in this query.
  sqlite3_stmt *stmt = NULL;
  const gchar *cquery = dt_collection_get_query(collection);
  complete_query = NULL;
  if(cquery && cquery[0] != '\0')
  {
    complete_query = dt_util_dstrcat(complete_query, "delete from selected_images where imgid not in (%s)", cquery);
    DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), complete_query, -1, &stmt, NULL);
    DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, 0);
    DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, -1);
    sqlite3_step(stmt);
    sqlite3_finalize(stmt);

    /* free allocated strings */
    g_free(complete_query);
  }


  /* raise signal of collection change, only if this is an original */
  if (!collection->clone)
    dt_control_signal_raise(darktable.signals, DT_SIGNAL_COLLECTION_CHANGED);

}
Example #25
0
void dt_collection_split_operator_datetime(const gchar *input, char **number1, char **number2, char **operator)
{
  GRegex *regex;
  GMatchInfo *match_info;
  int match_count;

  *number1 = *number2 = *operator= NULL;

  // we test the range expression first
  // 4 elements : date1 time1(optional) date2 time2(optional)
  regex = g_regex_new("^\\s*\\[\\s*(\\d{4}:\\d{2}:\\d{2})\\s*( "
                      "\\d{2}:\\d{2}:\\d{2})?\\s*;\\s*(\\d{4}:\\d{2}:\\d{2})\\s*( "
                      "\\d{2}:\\d{2}:\\d{2})?\\s*\\]\\s*$",
                      0, 0, NULL);
  g_regex_match_full(regex, input, -1, 0, 0, &match_info, NULL);
  match_count = g_match_info_get_match_count(match_info);

  if(match_count >= 4)
  {
    *number1 = g_match_info_fetch(match_info, 1);
    gchar *number1_time = g_match_info_fetch(match_info, 2);
    *number2 = g_match_info_fetch(match_info, 3);
    *operator= g_strdup("[]");

    if(!number1_time || strcmp(number1_time, "") == 0)
      *number1 = dt_util_dstrcat(*number1, " 00:00:00");
    else
      *number1 = dt_util_dstrcat(*number1, "%s", number1_time);

    if(match_count == 5)
    {
      gchar *number2_time = g_match_info_fetch(match_info, 4);
      *number2 = dt_util_dstrcat(*number2, "%s", number2_time);
      g_free(number2_time);
    }
    else
      *number2 = dt_util_dstrcat(*number2, " 23:59:59");

    if(number1_time) g_free(number1_time);
    g_match_info_free(match_info);
    g_regex_unref(regex);
    return;
  }

  g_match_info_free(match_info);
  g_regex_unref(regex);

  // and we test the classic comparaison operators
  // 2 elements : date time(optional)
  regex = g_regex_new("^\\s*(=|<|>|<=|>=|<>)?\\s*(\\d{4}:\\d{2}:\\d{2})\\s*( \\d{2}:\\d{2}:\\d{2})?\\s*$", 0,
                      0, NULL);
  g_regex_match_full(regex, input, -1, 0, 0, &match_info, NULL);
  match_count = g_match_info_get_match_count(match_info);

  if(match_count >= 3)
  {
    *operator= g_match_info_fetch(match_info, 1);
    *number1 = g_match_info_fetch(match_info, 2);
    // we fill the time part if it's not set
    if(match_count == 4)
    {
      gchar *nb_time = g_match_info_fetch(match_info, 3);
      *number1 = dt_util_dstrcat(*number1, "%s", nb_time);
      g_free(nb_time);
    }
    else if(*operator&& strcmp(*operator, ">") == 0)
      *number1 = dt_util_dstrcat(*number1, " 23:59:59");
    else if(*operator&& strcmp(*operator, ">=") == 0)
      *number1 = dt_util_dstrcat(*number1, " 00:00:00");
    else if(*operator&& strcmp(*operator, "<") == 0)
      *number1 = dt_util_dstrcat(*number1, " 00:00:00");
    else if(*operator&& strcmp(*operator, "<=") == 0)
      *number1 = dt_util_dstrcat(*number1, " 23:59:59");
    else if(*operator&& strcmp(*operator, "=") == 0)
      *number1 = dt_util_dstrcat(*number1, "%%");
    else if(*operator&& strcmp(*operator, "<>") == 0)
      *number1 = dt_util_dstrcat(*number1, "%%");
    else if(*operator&& strcmp(*operator, "") == 0)
      *number1 = dt_util_dstrcat(*number1, "%%");
    else if(!*operator)
      *number1 = dt_util_dstrcat(*number1, "%%");

    if(*operator&& strcmp(*operator, "") == 0)
    {
      g_free(*operator);
      *operator= NULL;
    }
  }

  g_match_info_free(match_info);
  g_regex_unref(regex);
}
Example #26
0
static gchar *get_query_string(const dt_collection_properties_t property, const gchar *text)
{
  char *escaped_text = sqlite3_mprintf("%q", text);
  gchar *query = NULL;

  switch(property)
  {
    case DT_COLLECTION_PROP_FILMROLL: // film roll
      if(!(escaped_text && *escaped_text))
        query = dt_util_dstrcat(query, "(film_id in (select id from film_rolls where folder like '%s%%'))",
                                escaped_text);
      else
        query = dt_util_dstrcat(query, "(film_id in (select id from film_rolls where folder like '%s'))",
                                escaped_text);
      break;

    case DT_COLLECTION_PROP_FOLDERS: // folders
      query = dt_util_dstrcat(query, "(film_id in (select id from film_rolls where folder like '%s%%'))",
                              escaped_text);
      break;

    case DT_COLLECTION_PROP_COLORLABEL: // colorlabel
    {
      int color = 0;
      if(!(escaped_text && *escaped_text) || strcmp(escaped_text, "%") == 0)
        query = dt_util_dstrcat(query, "(id in (select imgid from color_labels where color IS NOT NULL))");
      else
      {
        if(strcmp(escaped_text, _("red")) == 0)
          color = 0;
        else if(strcmp(escaped_text, _("yellow")) == 0)
          color = 1;
        else if(strcmp(escaped_text, _("green")) == 0)
          color = 2;
        else if(strcmp(escaped_text, _("blue")) == 0)
          color = 3;
        else if(strcmp(escaped_text, _("purple")) == 0)
          color = 4;
        query = dt_util_dstrcat(query, "(id in (select imgid from color_labels where color=%d))", color);
      }
    }
    break;

    case DT_COLLECTION_PROP_HISTORY: // history
      query = dt_util_dstrcat(query, "(id %s in (select imgid from history where imgid=images.id)) ",
                              (strcmp(escaped_text, _("altered")) == 0) ? "" : "not");
      break;

    case DT_COLLECTION_PROP_GEOTAGGING: // geotagging
      query = dt_util_dstrcat(query, "(id %s in (select id AS imgid from images where (longitude IS NOT NULL AND "
                                 "latitude IS NOT NULL))) ",
                              (strcmp(escaped_text, _("tagged")) == 0) ? "" : "not");
      break;

    case DT_COLLECTION_PROP_CAMERA: // camera
      if (!text || text[0] == '\0') // Optimize away the empty case
        query = dt_util_dstrcat(query, "(1=1)");
      else
      {
        // Start query with a false statement to avoid special casing the first condition
        query = dt_util_dstrcat(query, "((1=0)");
        GList *lists = NULL;
        dt_collection_get_makermodel(text, NULL, &lists);
        GList *element = lists;
        while (element)
        {
          GList *tuple = element->data;
          char *mk = sqlite3_mprintf("%q", tuple->data);
          char *md = sqlite3_mprintf("%q", tuple->next->data);
          query = dt_util_dstrcat(query, " or (maker = '%s' and model = '%s')", mk, md);
          sqlite3_free(mk);
          sqlite3_free(md);
          g_free(tuple->data);
          g_free(tuple->next->data);
          g_list_free(tuple);
          element = element->next;
        }
        g_list_free(lists);
        query = dt_util_dstrcat(query, ")");
      }
      break;
    case DT_COLLECTION_PROP_TAG: // tag
      query = dt_util_dstrcat(query, "(id in (select imgid from tagged_images as a join "
                                 "tags as b on a.tagid = b.id where name like '%s'))",
                              escaped_text);
      break;

    // TODO: How to handle images without metadata? In the moment they are not shown.
    // TODO: Autogenerate this code?
    case DT_COLLECTION_PROP_TITLE: // title
      query = dt_util_dstrcat(query, "(id in (select id from meta_data where key = %d and value like '%%%s%%'))",
                      DT_METADATA_XMP_DC_TITLE, escaped_text);
      break;
    case DT_COLLECTION_PROP_DESCRIPTION: // description
      query = dt_util_dstrcat(query, "(id in (select id from meta_data where key = %d and value like '%%%s%%'))",
                      DT_METADATA_XMP_DC_DESCRIPTION, escaped_text);
      break;
    case DT_COLLECTION_PROP_CREATOR: // creator
      query = dt_util_dstrcat(query, "(id in (select id from meta_data where key = %d and value like '%%%s%%'))",
                      DT_METADATA_XMP_DC_CREATOR, escaped_text);
      break;
    case DT_COLLECTION_PROP_PUBLISHER: // publisher
      query = dt_util_dstrcat(query, "(id in (select id from meta_data where key = %d and value like '%%%s%%'))",
                      DT_METADATA_XMP_DC_PUBLISHER, escaped_text);
      break;
    case DT_COLLECTION_PROP_RIGHTS: // rights
      query = dt_util_dstrcat(query, "(id in (select id from meta_data where key = %d and value like '%%%s%%'))",
                      DT_METADATA_XMP_DC_RIGHTS, escaped_text);
      break;
    case DT_COLLECTION_PROP_LENS: // lens
      query = dt_util_dstrcat(query, "(lens like '%%%s%%')", escaped_text);
      break;

    case DT_COLLECTION_PROP_FOCAL_LENGTH: // focal length
    {
      gchar *operator, *number1, *number2;
      dt_collection_split_operator_number(escaped_text, &number1, &number2, &operator);

      if(operator&& strcmp(operator, "[]") == 0)
      {
        if(number1 && number2)
          query = dt_util_dstrcat(query, "((focal_length >= %s) AND (focal_length <= %s))", number1, number2);
      }
      else if(operator&& number1)
        query = dt_util_dstrcat(query, "(focal_length %s %s)", operator, number1);
      else if(number1)
        query = dt_util_dstrcat(query, "(focal_length = %s)", number1);
      else
        query = dt_util_dstrcat(query, "(focal_length like '%%%s%%')", escaped_text);

      g_free(operator);
      g_free(number1);
      g_free(number2);
    }
    break;

    case DT_COLLECTION_PROP_ISO: // iso
    {
      gchar *operator, *number1, *number2;
      dt_collection_split_operator_number(escaped_text, &number1, &number2, &operator);

      if(operator&& strcmp(operator, "[]") == 0)
      {
        if(number1 && number2)
          query = dt_util_dstrcat(query, "((iso >= %s) AND (iso <= %s))", number1, number2);
      }
      else if(operator&& number1)
        query = dt_util_dstrcat(query, "(iso %s %s)", operator, number1);
      else if(number1)
        query = dt_util_dstrcat(query, "(iso = %s)", number1);
      else
        query = dt_util_dstrcat(query, "(iso like '%%%s%%')", escaped_text);

      g_free(operator);
      g_free(number1);
      g_free(number2);
    }
    break;

    case DT_COLLECTION_PROP_APERTURE: // aperture
    {
      gchar *operator, *number1, *number2;
      dt_collection_split_operator_number(escaped_text, &number1, &number2, &operator);

      if(operator&& strcmp(operator, "[]") == 0)
      {
        if(number1 && number2)
          query = dt_util_dstrcat(query, "((round(aperture,1) >= %s) AND (round(aperture,1) <= %s))", number1,
                                  number2);
      }
      else if(operator&& number1)
        query = dt_util_dstrcat(query, "(round(aperture,1) %s %s)", operator, number1);
      else if(number1)
        query = dt_util_dstrcat(query, "(round(aperture,1) = %s)", number1);
      else
        query = dt_util_dstrcat(query, "(round(aperture,1) like '%%%s%%')", escaped_text);

      g_free(operator);
      g_free(number1);
      g_free(number2);
    }
    break;

    case DT_COLLECTION_PROP_FILENAME: // filename
      query = dt_util_dstrcat(query, "(filename like '%%%s%%')", escaped_text);
      break;

    case DT_COLLECTION_PROP_DAY:
    // query = dt_util_dstrcat(query, "(datetime_taken like '%%%s%%')", escaped_text);
    // break;

    case DT_COLLECTION_PROP_TIME:
    {
      gchar *operator, *number1, *number2;
      dt_collection_split_operator_datetime(escaped_text, &number1, &number2, &operator);

      if(operator&& strcmp(operator, "[]") == 0)
      {
        if(number1 && number2)
          query = dt_util_dstrcat(query, "((datetime_taken >= '%s') AND (datetime_taken <= '%s'))", number1,
                                  number2);
      }
      else if(operator&& strcmp(operator, "=") == 0 && number1)
        query = dt_util_dstrcat(query, "(datetime_taken like '%s')", number1);
      else if(operator&& strcmp(operator, "<>") == 0 && number1)
        query = dt_util_dstrcat(query, "(datetime_taken not like '%s')", number1);
      else if(operator&& number1)
        query = dt_util_dstrcat(query, "(datetime_taken %s '%s')", operator, number1);
      else if(number1)
        query = dt_util_dstrcat(query, "(datetime_taken like '%s')", number1);
      else
        query = dt_util_dstrcat(query, "(datetime_taken like '%%%s%%')", escaped_text);

      g_free(operator);
      g_free(number1);
      g_free(number2);
    }
    break;

    default:
      // we shouldn't be here
      break;
  }
  sqlite3_free(escaped_text);

  if(!query) // We've screwed up and not done a query string, send a placeholder
    query = dt_util_dstrcat(query, "(1=1)");

  return query;
}
Example #27
0
gchar *
dt_collection_get_sort_query(const dt_collection_t *collection)
{
  gchar *sq = NULL;

  if (collection->params.descending)
  {
    switch(collection->params.sort)
    {
      case DT_COLLECTION_SORT_DATETIME:
        sq = dt_util_dstrcat(sq, ORDER_BY_QUERY, "datetime_taken desc, filename, version");
        break;

      case DT_COLLECTION_SORT_RATING:
        sq = dt_util_dstrcat(sq, ORDER_BY_QUERY, "flags & 7, filename, version");
        break;

      case DT_COLLECTION_SORT_FILENAME:
        sq = dt_util_dstrcat(sq, ORDER_BY_QUERY, "filename desc, version");
        break;

      case DT_COLLECTION_SORT_ID:
        sq = dt_util_dstrcat(sq, ORDER_BY_QUERY, "id desc");
        break;

      case DT_COLLECTION_SORT_COLOR:
        sq = dt_util_dstrcat(sq, ORDER_BY_QUERY, "color, filename, version");
        break;

      case DT_COLLECTION_SORT_NONE:
        //shouldn't happen
        break;
    }
  }
  else
  {
    switch(collection->params.sort)
    {
      case DT_COLLECTION_SORT_DATETIME:
        sq = dt_util_dstrcat(sq, ORDER_BY_QUERY, "datetime_taken, filename, version");
        break;

      case DT_COLLECTION_SORT_RATING:
        sq = dt_util_dstrcat(sq, ORDER_BY_QUERY, "flags & 7 desc, filename, version");
        break;

      case DT_COLLECTION_SORT_FILENAME:
        sq = dt_util_dstrcat(sq, ORDER_BY_QUERY, "filename, version");
        break;

      case DT_COLLECTION_SORT_ID:
        sq = dt_util_dstrcat(sq, ORDER_BY_QUERY, "id");
        break;

      case DT_COLLECTION_SORT_COLOR:
        sq = dt_util_dstrcat(sq, ORDER_BY_QUERY, "color desc, filename, version");
        break;

      case DT_COLLECTION_SORT_NONE:
        //shouldn't happen
        break;
    }
  }

  return sq;
}
Example #28
0
int
dt_collection_update (const dt_collection_t *collection)
{
  uint32_t result;
  gchar *wq, *sq, *selq, *query;
  wq = sq = selq = query = NULL;

  /* build where part */
  if (!(collection->params.query_flags&COLLECTION_QUERY_USE_ONLY_WHERE_EXT))
  {
    int need_operator = 0;
    dt_collection_filter_t rating = collection->params.rating;
    if(rating == DT_COLLECTION_FILTER_NOT_REJECT) rating = DT_COLLECTION_FILTER_STAR_NO;

    /* add default filters */
    if (collection->params.filter_flags & COLLECTION_FILTER_FILM_ID)
    {
      wq = dt_util_dstrcat(wq, "(film_id = %d)", collection->params.film_id);
      need_operator = 1;
    }
    // DON'T SELECT IMAGES MARKED TO BE DELETED.
    wq = dt_util_dstrcat(wq, " %s (flags & %d) != %d", (need_operator)?"and":((need_operator=1)?"":""), DT_IMAGE_REMOVE, DT_IMAGE_REMOVE);

    if (collection->params.filter_flags & COLLECTION_FILTER_CUSTOM_COMPARE)
      wq = dt_util_dstrcat(wq, " %s (flags & 7) %s %d and (flags & 7) != 6", (need_operator)?"and":((need_operator=1)?"":""), comparators[collection->params.comparator], rating - 1);
    else if (collection->params.filter_flags & COLLECTION_FILTER_ATLEAST_RATING)
      wq = dt_util_dstrcat(wq, " %s (flags & 7) >= %d and (flags & 7) != 6", (need_operator)?"and":((need_operator=1)?"":""), rating - 1);
    else if (collection->params.filter_flags & COLLECTION_FILTER_EQUAL_RATING)
      wq = dt_util_dstrcat(wq, " %s (flags & 7) == %d", (need_operator)?"and":((need_operator=1)?"":""), rating - 1);

    if (collection->params.filter_flags & COLLECTION_FILTER_ALTERED)
      wq = dt_util_dstrcat(wq, " %s id in (select imgid from history where imgid=id)", (need_operator)?"and":((need_operator=1)?"":"") );
    else if (collection->params.filter_flags & COLLECTION_FILTER_UNALTERED)
      wq = dt_util_dstrcat(wq, " %s id not in (select imgid from history where imgid=id)", (need_operator)?"and":((need_operator=1)?"":"") );

    /* add where ext if wanted */
    if ((collection->params.query_flags&COLLECTION_QUERY_USE_WHERE_EXT))
      wq = dt_util_dstrcat(wq, " %s %s", (need_operator)?"and":"", collection->where_ext);
  }
  else
    wq = dt_util_dstrcat(wq, "%s", collection->where_ext);

  /* grouping */
  if(darktable.gui && darktable.gui->grouping)
  {
    wq = dt_util_dstrcat(wq, " and (group_id = id or group_id = %d)", darktable.gui->expanded_group_id);
  }

  /* build select part includes where */
  if (collection->params.sort == DT_COLLECTION_SORT_COLOR && (collection->params.query_flags & COLLECTION_QUERY_USE_SORT))
    selq = dt_util_dstrcat(selq, "select distinct id from (select * from images where %s) as a left outer join color_labels as b on a.id = b.imgid", wq);
  else if(collection->params.query_flags&COLLECTION_QUERY_USE_ONLY_WHERE_EXT)
    selq = dt_util_dstrcat(selq, "select distinct images.id from images %s",wq);
  else
    selq = dt_util_dstrcat(selq, "select distinct id from images where %s",wq);



  /* build sort order part */
  if (!(collection->params.query_flags&COLLECTION_QUERY_USE_ONLY_WHERE_EXT)  && (collection->params.query_flags&COLLECTION_QUERY_USE_SORT))
  {
    sq = dt_collection_get_sort_query(collection);
  }

  /* store the new query */
  query = dt_util_dstrcat(query, "%s %s%s", selq, sq?sq:"", (collection->params.query_flags&COLLECTION_QUERY_USE_LIMIT)?" "LIMIT_QUERY:"");
  result = _dt_collection_store(collection, query);

  /* free memory used */
  g_free(sq);
  g_free(wq);
  g_free(selq);
  g_free (query);

  /* update the cached count. collection isn't a real const anyway, we are writing to it in _dt_collection_store, too. */
  ((dt_collection_t*)collection)->count = _dt_collection_compute_count(collection);
  dt_collection_hint_message(collection);

  return result;
}
Example #29
0
static gboolean _lib_location_search(gpointer user_data)
{
  GMarkupParseContext *ctx = NULL;
  CURL *curl = NULL;
  CURLcode res;
  GError *err = NULL;

  dt_lib_module_t *self = (dt_lib_module_t *)user_data;
  dt_lib_location_t *lib   = (dt_lib_location_t *)self->data;
  gchar *query = NULL, *text = NULL ;

  /* get escaped search text */
  text = g_uri_escape_string(gtk_entry_get_text(lib->search), NULL, FALSE);

  if (!(text && *text))
    goto bail_out;

  /* clean up previous results before adding new */
  g_free(lib->response);
  lib->response = NULL;
  lib->response_size = 0;

  g_list_free_full(lib->places, g_free);
  lib->places = NULL;

  gtk_container_foreach(GTK_CONTAINER(lib->result),(GtkCallback)gtk_widget_destroy,NULL);

  /* build the query url */
  query = dt_util_dstrcat(query, "http://nominatim.openstreetmap.org/search/%s?format=xml&limit=%d",
                          text, LIMIT_RESULT);
  /* load url */
  curl = curl_easy_init();
  if (!curl)
    goto bail_out;

  curl_easy_setopt(curl, CURLOPT_URL, query);
  // curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, lib);
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _lib_location_curl_write_data);

  res = curl_easy_perform(curl);
  if (res != 0)
    goto bail_out;

  if (!lib->response)
    goto bail_out;

  /* parse xml response and populate the result list */
  ctx = g_markup_parse_context_new(&_lib_location_parser, 0, lib, NULL);
  g_markup_parse_context_parse(ctx, lib->response, lib->response_size, &err);
  if (err)
    goto bail_out;

  /* add the places into the result list */
  GList *item = lib->places;
  if (!item)
    goto bail_out;

  while(item)
  {
    _lib_location_result_t *p = (_lib_location_result_t *)item->data;
    fprintf(stderr, "(%f,%f) %s\n", p->lon, p->lat, p->name);
    item = g_list_next(item);
  }

  /* cleanup an exit search job */
bail_out:
  if (err)
  {
    fprintf(stderr, "location search: %s\n", err->message);
    g_error_free(err);
  }

  if (curl)
    curl_easy_cleanup(curl);

  g_free(text);
  g_free(query);

  if (ctx)
    g_markup_parse_context_free(ctx);

  /* enable the widgets */
  gtk_widget_set_sensitive(GTK_WIDGET(lib->search), TRUE);
  // gtk_widget_set_sensitive(lib->result, FALSE);

  return FALSE;
}
Example #30
0
static void _lib_import_folder_callback(GtkWidget *widget, gpointer user_data)
{
  GtkWidget *win = dt_ui_main_window(darktable.gui->ui);
  GtkWidget *filechooser = gtk_file_chooser_dialog_new(
      _("import film"), GTK_WINDOW(win), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, _("_Cancel"),
      GTK_RESPONSE_CANCEL, _("_Open"), GTK_RESPONSE_ACCEPT, (char *)NULL);

  gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(filechooser), TRUE);

  char *last_directory = dt_conf_get_string("ui_last/import_last_directory");
  if(last_directory != NULL)
  {
    gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(filechooser), last_directory);
    g_free(last_directory);
  }

  dt_lib_import_metadata_t metadata;
  gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(filechooser),
                                    _lib_import_get_extra_widget(&metadata, TRUE));

  // run the dialog
  if(gtk_dialog_run(GTK_DIALOG(filechooser)) == GTK_RESPONSE_ACCEPT)
  {
    dt_conf_set_string("ui_last/import_last_directory",
                       gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(filechooser)));
    _lib_import_evaluate_extra_widget(&metadata, TRUE);

    char *filename = NULL, *first_filename = NULL;
    GSList *list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(filechooser));
    GSList *it = list;

    /* reset filter so that view isn't empty */
    dt_view_filter_reset(darktable.view_manager, TRUE);

    /* for each selected folder add import job */
    while(it)
    {
      filename = (char *)it->data;
      dt_film_import(filename);
      if(!first_filename)
      {
        first_filename = g_strdup(filename);
        if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(metadata.recursive)))
          first_filename = dt_util_dstrcat(first_filename, "%%");
      }
      g_free(filename);
      it = g_slist_next(it);
    }

    /* update collection to view import */
    if(first_filename)
    {
      dt_conf_set_int("plugins/lighttable/collect/num_rules", 1);
      dt_conf_set_int("plugins/lighttable/collect/item0", 0);
      dt_conf_set_string("plugins/lighttable/collect/string0", first_filename);
      dt_collection_update_query(darktable.collection);
      g_free(first_filename);
    }


    g_slist_free(list);
  }
  gtk_widget_destroy(metadata.frame);
  gtk_widget_destroy(filechooser);
  gtk_widget_queue_draw(dt_ui_center(darktable.gui->ui));
}