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); }
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); }
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); }
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); }
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); }
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; }
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; }
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; }
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); }
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; }
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); }
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; }
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; }
/** * @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; }
/* 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); }
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; }
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); }
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); }
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); }
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; }
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; }
/** * 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; }
/** * @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; }
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); }
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); }
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; }
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; }
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; }
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; }
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)); }