48#include <gdk/gdkkeysyms.h>
103#define LIMIT_RESULT 5
111 const char **attribute_names,
const gchar **attribute_values,
112 gpointer user_data, GError **
error);
118 return _(
"find location");
123 static const char *
v[] = {
"map", NULL};
136 gtk_entry_set_text(lib->
search,
"");
156 lib->
search = GTK_ENTRY(gtk_entry_new());
176 if(event->type == GDK_ENTER_NOTIFY)
177 gtk_widget_set_state_flags(widget, GTK_STATE_FLAG_PRELIGHT,
FALSE);
179 gtk_widget_unset_state_flags(widget, GTK_STATE_FLAG_PRELIGHT);
187 eb = gtk_event_box_new();
188 gtk_widget_set_name(eb,
"dt-map-location");
195 w = gtk_label_new(place->
name);
196 gtk_label_set_line_wrap(GTK_LABEL(w),
TRUE);
197 gtk_widget_set_halign(w, GTK_ALIGN_START);
198 g_object_set(G_OBJECT(w),
"xalign", 0.0, (gchar *)0);
199 gtk_box_pack_start(GTK_BOX(vb), w,
FALSE,
FALSE, 0);
204 gchar *location = g_strconcat(
lat,
", ",
lon, NULL);
205 w = gtk_label_new(location);
209 gtk_label_set_line_wrap(GTK_LABEL(w),
TRUE);
210 gtk_widget_set_halign(w, GTK_ALIGN_START);
211 gtk_box_pack_start(GTK_BOX(vb), w,
FALSE,
FALSE, 0);
214 gtk_container_add(GTK_CONTAINER(eb), vb);
216 gtk_widget_show_all(eb);
276 g_object_unref(lib->
marker);
307 if(isnan(
p->bbox.lon1) || isnan(
p->bbox.lat1) || isnan(
p->bbox.lon2) || isnan(
p->bbox.lat2))
338 for(
const GList *item = lib->
places; item; item = g_list_next(item))
342 gtk_widget_show(lib->
result);
356 GMarkupParseContext *ctx = NULL;
363 gchar *query = NULL, *text = NULL;
366 text = g_uri_escape_string(gtk_entry_get_text(lib->
search), NULL,
FALSE);
368 if(!(text && *text))
goto bail_out;
375 query = g_strdup_printf(search_url, text,
LIMIT_RESULT);
377 curl = curl_easy_init();
382 curl_easy_setopt(curl, CURLOPT_URL, query);
383 curl_easy_setopt(curl, CURLOPT_WRITEDATA, lib);
386 curl_easy_setopt(curl, CURLOPT_TIMEOUT, 20L);
388 res = curl_easy_perform(curl);
389 if(res != 0)
goto bail_out;
396 if(err)
goto bail_out;
399 GList *item = lib->
places;
413 fprintf(stderr,
"location search: %s\n", err->message);
417 if(curl) curl_easy_cleanup(curl);
422 if(ctx) g_markup_parse_context_free(ctx);
425 gtk_widget_set_sensitive(GTK_WIDGET(lib->
search),
TRUE);
444 const gchar *text = gtk_entry_get_text(lib->
search);
448 gtk_widget_set_sensitive(GTK_WIDGET(lib->
search),
FALSE);
457 const char **attribute_names,
const gchar **attribute_values,
458 gpointer user_data, GError **e)
463 if(strcmp(element_name,
"place") != 0)
return;
482 int max_outline_nodes =
dt_conf_get_int(
"plugins/map/max_outline_nodes");
485 const gchar **aname = attribute_names;
486 const gchar **avalue = attribute_values;
491 if(strcmp(*aname,
"display_name") == 0)
493 place->
name = g_strdup(*avalue);
494 if(!(place->
name))
goto bail_out;
496 else if(strcmp(*aname,
"lon") == 0)
497 place->
lon = g_strtod(*avalue, NULL);
498 else if(strcmp(*aname,
"lat") == 0)
499 place->
lat = g_strtod(*avalue, NULL);
500 else if(strcmp(*aname,
"boundingbox") == 0)
503 float lon1, lat1, lon2, lat2;
505 lat1 = g_ascii_strtod(*avalue, &endptr);
506 if(*endptr !=
',')
goto broken_bbox;
509 lat2 = g_ascii_strtod(endptr, &endptr);
510 if(*endptr !=
',')
goto broken_bbox;
513 lon1 = g_ascii_strtod(endptr, &endptr);
514 if(*endptr !=
',')
goto broken_bbox;
517 lon2 = g_ascii_strtod(endptr, &endptr);
518 if(*endptr !=
'\0')
goto broken_bbox;
528 else if(show_outline &&
529 strcmp(*aname,
"geotext") == 0 &&
532 if(g_str_has_prefix(*avalue,
"POINT"))
535 float lon = g_ascii_strtod(*avalue + strlen(
"POINT("), &endptr);
536 float lat = g_ascii_strtod(endptr, &endptr);
546 else if(g_str_has_prefix(*avalue,
"LINESTRING")
547#ifdef HAVE_OSMGPSMAP_110_OR_NEWER
548 || g_str_has_prefix(*avalue,
"POLYGON")
549 || g_str_has_prefix(*avalue,
"MULTIPOLYGON")
554 const char *startptr = *avalue;
556 while(startptr && (*startptr ==
' ' || *startptr ==
'(' || (*startptr >=
'A' && *startptr <=
'Z')))
562 float lon = g_ascii_strtod(startptr, &endptr);
563 float lat = g_ascii_strtod(endptr, &endptr);
570 if(g_str_has_prefix(endptr,
")),((") || g_str_has_prefix(endptr,
"),("))
580 startptr = endptr + (g_str_has_prefix(endptr,
")),((") ? 5 : 3);
599 if(*endptr !=
',' ||
i > max_outline_nodes)
624 gchar *s = g_strndup(*avalue, 100);
625 fprintf(stderr,
"unsupported outline: %s%s\n", s, strlen(s) == strlen(*avalue) ?
"" :
" ...");
629 else if(strcmp(*aname,
"type") == 0)
632 if(strcmp(*avalue,
"village") == 0)
634 else if(strcmp(*avalue,
"hamlet") == 0)
636 else if(strcmp(*avalue,
"city") == 0)
638 else if(strcmp(*avalue,
"administrative") == 0)
640 else if(strcmp(*avalue,
"residental") == 0)
642 else if(strcmp(*avalue,
"residential") == 0)
652 if(isnan(place->
lon) || isnan(place->
lat))
goto bail_out;
683 const size_t size_name = strlen(location->
name) + 1;
684 const size_t size_points = 2 *
sizeof(float) * g_list_length(location->
marker_points);
685 const size_t size_total = size_fixed + size_name + size_points;
687 void *params = malloc(size_total);
690 params_fixed->
type = location->
type;
691 params_fixed->
lon = location->
lon;
692 params_fixed->
lat = location->
lat;
699 memcpy((uint8_t *)params + size_fixed, location->
name, size_name);
701 float *points = (
float *)((uint8_t *)params + size_fixed + size_name);
702 for(GList *iter = location->
marker_points; iter; iter = g_list_next(iter), points += 2)
705 points[0] =
point->lat;
706 points[1] =
point->lon;
719 if(
size < size_fixed)
return 1;
722 const char *
name = (
char *)((uint8_t *)params + size_fixed);
723 const size_t size_name = strlen(
name) + 1;
725 if(size_fixed + size_name >
size)
return 1;
727 const size_t size_points =
size - (size_fixed + size_name);
729 if(size_points % 2 *
sizeof(
float) != 0)
return 1;
734 location->
type = params_fixed->
type;
735 location->
lon = params_fixed->
lon;
736 location->
lat = params_fixed->
lat;
745 for(
const float *points = (
float *)((uint8_t *)params + size_fixed + size_name); (uint8_t *)points < (uint8_t *)params +
size; points += 2)
756 gtk_entry_set_text(lib->
search,
"");
static void error(char *msg)
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
const char darktable_package_string[]
int dt_conf_get_bool(const char *name)
int dt_conf_get_int(const char *name)
const char * dt_conf_get_string_const(const char *name)
#define g_list_is_singleton(list)
#define DT_MODULE(MODVER)
static void dt_free_gpointer(gpointer ptr)
float dt_aligned_pixel_simd_t __attribute__((vector_size(16), aligned(16)))
Enable aggressive floating-point arithmetic optimizations, in denormals handling. Set through user pr...
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
void dt_gui_container_destroy_children(GtkContainer *container)
void dt_accels_disconnect_on_text_input(GtkWidget *widget)
Disconnects accels when a text or search entry gets the focus, and reconnects them when it looses it....
#define DT_GUI_BOX_SPACING
static void _show_location(dt_lib_location_t *lib, _lib_location_result_t *p)
void gui_reset(dt_lib_module_t *self)
int set_params(dt_lib_module_t *self, const void *params, int size)
static void clear_search(dt_lib_location_t *lib)
void * get_params(dt_lib_module_t *self, int *size)
static void _clear_markers(dt_lib_location_t *lib)
static size_t _lib_location_curl_write_data(void *buffer, size_t size, size_t nmemb, void *userp)
void gui_cleanup(dt_lib_module_t *self)
static void _lib_location_parser_start_element(GMarkupParseContext *cxt, const char *element_name, const char **attribute_names, const gchar **attribute_values, gpointer user_data, GError **error)
static void _lib_location_entry_activated(GtkButton *button, gpointer user_data)
static GMarkupParser _lib_location_parser
uint32_t container(dt_lib_module_t *self)
static gboolean _lib_location_result_item_activated(GtkButton *button, GdkEventButton *ev, gpointer user_data)
static void _lib_location_search_finish(gpointer user_data)
static gboolean _event_box_enter_leave(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
static void free_location(_lib_location_result_t *location)
void gui_init(dt_lib_module_t *self)
const char ** views(dt_lib_module_t *self)
@ LOCATION_TYPE_ADMINISTRATIVE
@ LOCATION_TYPE_RESIDENTIAL
static int32_t _lib_location_place_get_zoom(_lib_location_result_t *place)
static gboolean _lib_location_search(gpointer user_data)
static GtkWidget * _lib_location_place_widget_new(dt_lib_location_t *lib, _lib_location_result_t *place)
#define DT_DEBUG_CONTROL_SIGNAL_RAISE(ctlsig, signal,...)
@ DT_SIGNAL_LOCATION_CHANGED
struct _GtkWidget GtkWidget
const float const float param
_lib_location_result_t * result
dt_geo_map_display_t marker_type
_lib_location_type_t type
struct dt_control_signal_t * signals
struct dt_view_manager_t * view_manager
_lib_location_result_t * selected_location
dt_geo_map_display_t marker_type
dt_geo_map_display_t marker_type
_lib_location_type_t type
gchar * dt_util_longitude_str(float longitude)
gchar * dt_util_latitude_str(float latitude)
@ DT_UI_CONTAINER_PANEL_RIGHT_CENTER