elementary: add elm_map_name_search

SVN revision: 77935
This commit is contained in:
Michael BOUCHAUD 2012-10-12 10:27:08 +00:00
parent 9a8fc5433e
commit b6c771c97c
5 changed files with 241 additions and 17 deletions

View File

@ -593,3 +593,6 @@
* Add access features to multibuttonentry
* Fix diskselector bug on round with appended items with more
than 4 items.
2012-10-12 Michael Bouchaud (yoz)
* Add elm_map_name_search

View File

@ -10,6 +10,7 @@ Additions:
* Add the toolbar API which expand the transverse length.
* Add a way to know which month is displayed in elm_calendar
* Add color picker to elm_colorselector.
* Add a search API to list all localisations corresponding to a name in map
Improvements:

View File

@ -33,6 +33,7 @@ EAPI const char ELM_MAP_PAN_SMART_NAME[] = "elm_map_pan";
#define NOMINATIM_PLACE "place"
#define NOMINATIM_ATTR_LON "lon"
#define NOMINATIM_ATTR_LAT "lat"
#define NOMINATIM_ATTR_ADDRESS "display_name"
#ifdef HAVE_ELEMENTARY_ECORE_CON
@ -2801,6 +2802,11 @@ _xml_name_attrs_dump_cb(void *data,
dump->lon = _elm_atof(value);
else if (!strncmp(key, NOMINATIM_ATTR_LAT, sizeof(NOMINATIM_ATTR_LAT)))
dump->lat = _elm_atof(value);
else if (!strncmp(key, NOMINATIM_ATTR_ADDRESS, sizeof(NOMINATIM_ATTR_ADDRESS)))
{
if (!dump->address)
dump->address = strdup(value);
}
return EINA_TRUE;
}
@ -2913,6 +2919,32 @@ _xml_name_dump_cb(void *data,
return EINA_TRUE;
}
static Eina_Bool
_xml_name_dump_list_cb(void *data,
Eina_Simple_XML_Type type,
const char *value,
unsigned offset,
unsigned length)
{
Elm_Map_Name_List *name_list = data;
Elm_Map_Name *name;
Name_Dump dump = {0, NULL, 0.0, 0.0};
_xml_name_dump_cb(&dump, type, value, offset, length);
name = calloc(1, sizeof(Elm_Map_Name));
if (!name) return EINA_FALSE;
if (dump.address)
{
name->address = strdup(dump.address);
name->lon = dump.lon;
name->lat = dump.lat;
name->wsd = name_list->wsd;
name_list->names = eina_list_append(name_list->names, name);
name->wsd->names = eina_list_append(name->wsd->names, name);
}
return EINA_TRUE;
}
static void
_kml_parse(Elm_Map_Route *r)
{
@ -3052,6 +3084,39 @@ _name_parse(Elm_Map_Name *n)
}
}
static void
_name_list_parse(Elm_Map_Name_List *nl)
{
FILE *f;
EINA_SAFETY_ON_NULL_RETURN(nl);
EINA_SAFETY_ON_NULL_RETURN(nl->fname);
f = fopen(nl->fname, "rb");
if (f)
{
long sz;
fseek(f, 0, SEEK_END);
sz = ftell(f);
if (sz > 0)
{
char *buf;
fseek(f, 0, SEEK_SET);
buf = malloc(sz);
if (buf)
{
if (fread(buf, 1, sz, f))
{
eina_simple_xml_parse
(buf, sz, EINA_TRUE, _xml_name_dump_list_cb, nl);
}
}
}
fclose(f);
}
}
static void
_route_cb(void *data,
const char *file,
@ -3123,6 +3188,68 @@ _name_cb(void *data,
"elm,state,busy,stop", "elm");
}
static void
_name_list_cb(void *data,
const char *file,
int status)
{
Elm_Map_Name_List *name_list;
Elm_Map_Smart_Data *sd;
EINA_SAFETY_ON_NULL_RETURN(data);
EINA_SAFETY_ON_NULL_RETURN(file);
name_list = data;
sd = name_list->wsd;
name_list->job = NULL;
if (status == 200)
{
_name_list_parse(name_list);
INF("Name List request success address");
if (name_list->cb)
name_list->cb(name_list->data, ELM_WIDGET_DATA(sd)->obj,
name_list->names);
evas_object_smart_callback_call
(ELM_WIDGET_DATA(sd)->obj, SIG_NAME_LOADED, NULL);
}
else
{
ERR("Name List request failed: %d", status);
if (name_list->cb)
name_list->cb(name_list->data, ELM_WIDGET_DATA(sd)->obj, NULL);
evas_object_smart_callback_call
(ELM_WIDGET_DATA(sd)->obj, SIG_NAME_LOADED_FAIL, NULL);
}
edje_object_signal_emit(ELM_WIDGET_DATA(sd)->resize_obj,
"elm,state,busy,stop", "elm");
free(name_list->fname);
free(name_list);
}
static char *
_prepare_download()
{
char fname[PATH_MAX];
{
const char *cachedir;
#ifdef ELM_EFREET
snprintf(fname, sizeof(fname), "%s" CACHE_NAME_ROOT,
efreet_cache_home_get());
(void)cachedir;
#else
cachedir = getenv("XDG_CACHE_HOME");
snprintf(fname, sizeof(fname), "%s/%s" CACHE_NAME_ROOT, getenv("HOME"),
cachedir ? : "/.config");
#endif
if (!ecore_file_exists(fname)) ecore_file_mkpath(fname);
}
return strdup(fname);
}
static Elm_Map_Name *
_name_request(const Evas_Object *obj,
int method,
@ -3134,31 +3261,18 @@ _name_request(const Evas_Object *obj,
{
char *url;
Elm_Map_Name *name;
char fname[PATH_MAX], fname2[PATH_MAX];
char *fname, fname2[PATH_MAX];
ELM_MAP_DATA_GET(obj, sd);
EINA_SAFETY_ON_NULL_RETURN_VAL(sd->src_name, NULL);
{
const char *cachedir;
#ifdef ELM_EFREET
snprintf(fname, sizeof(fname), "%s" CACHE_NAME_ROOT,
efreet_cache_home_get());
(void)cachedir;
#else
cachedir = getenv("XDG_CACHE_HOME");
snprintf(fname, sizeof(fname), "%s/%s" CACHE_NAME_ROOT, getenv("HOME"),
cachedir ? : "/.config");
#endif
if (!ecore_file_exists(fname)) ecore_file_mkpath(fname);
}
fname = _prepare_download();
url = sd->src_name->url_cb
(ELM_WIDGET_DATA(sd)->obj, method, address, lon, lat);
(ELM_WIDGET_DATA(sd)->obj, method, address, lon, lat);
if (!url)
{
ERR("Name URL is NULL");
free(fname);
return NULL;
}
@ -3183,10 +3297,12 @@ _name_request(const Evas_Object *obj,
if (name->address) free(name->address);
free(name->fname);
free(name);
free(fname);
return NULL;
}
INF("Name requested from %s to %s", url, name->fname);
free(url);
free(fname);
sd->names = eina_list_append(sd->names, name);
evas_object_smart_callback_call
@ -3196,6 +3312,60 @@ _name_request(const Evas_Object *obj,
return name;
}
static Eina_List *
_name_list_request(const Evas_Object *obj,
int method,
const char *address,
double lon,
double lat,
Elm_Map_Name_List_Cb name_cb,
void *data)
{
char *url;
Elm_Map_Name_List *name_list;
char *fname, fname2[PATH_MAX];
ELM_MAP_DATA_GET(obj, sd);
EINA_SAFETY_ON_NULL_RETURN_VAL(sd->src_name, NULL);
fname = _prepare_download();
url = sd->src_name->url_cb
(ELM_WIDGET_DATA(sd)->obj, method, address, lon, lat);
if (!url)
{
ERR("Name URL is NULL");
free(fname);
return NULL;
}
name_list = ELM_NEW(Elm_Map_Name_List);
name_list->wsd = sd;
snprintf(fname2, sizeof(fname2), "%s/%d", fname, rand());
name_list->fname = strdup(fname2);
name_list->cb = name_cb;
name_list->data = data;
if (!ecore_file_download_full(url, name_list->fname, _name_list_cb,
NULL, name_list,
&(name_list->job), sd->ua) || !(name_list->job))
{
ERR("Can't request Name from %s to %s", url, name_list->fname);
free(name_list->fname);
free(name_list);
free(fname);
return NULL;
}
INF("Name requested from %s to %s", url, name_list->fname);
free(url);
free(fname);
evas_object_smart_callback_call
(ELM_WIDGET_DATA(sd)->obj, SIG_NAME_LOAD, name_list->names);
edje_object_signal_emit(ELM_WIDGET_DATA(sd)->resize_obj,
"elm,state,busy,start", "elm");
return name_list->names;
}
static Evas_Event_Flags
_pinch_zoom_start_cb(void *data,
void *event_info __UNUSED__)
@ -4746,6 +4916,25 @@ elm_map_name_add(const Evas_Object *obj,
#endif
}
EAPI void
elm_map_name_search(const Evas_Object *obj,
const char *address,
Elm_Map_Name_List_Cb name_cb,
void *data)
{
#ifdef HAVE_ELEMENTARY_ECORE_CON
ELM_MAP_CHECK(obj);
if (address)
_name_list_request(obj, ELM_MAP_NAME_METHOD_SEARCH, address, 0, 0,
name_cb, data);
#else
(void) obj;
(void address);
(void) name_cb;
(void) data;
#endif
}
EAPI void
elm_map_name_del(Elm_Map_Name *name)
{

View File

@ -197,6 +197,7 @@ typedef Evas_Object *(*Elm_Map_Group_Icon_Get_Func)(Evas_Object *o
typedef void (*Elm_Map_Overlay_Get_Cb)(void *data, Evas_Object *map, Elm_Map_Overlay *overlay); /**< Get callback function for the overlay. */
typedef void (*Elm_Map_Overlay_Del_Cb)(void *data, Evas_Object *map, Elm_Map_Overlay *overlay); /**< Det callback function for the overlay. @since 1.7 */
typedef void (*Elm_Map_Name_Cb)(void *data, Evas_Object *map, Elm_Map_Name *name); /**< Async-callback function for the name request. */
typedef void (*Elm_Map_Name_List_Cb)(void *data, Evas_Object *map, Eina_List *name_list); /**< Async-callback function for the name list request. */
typedef void (*Elm_Map_Route_Cb)(void *data, Evas_Object *map, Elm_Map_Route *route); /**< Async-callback function for the route request. */
/**
@ -1485,6 +1486,22 @@ EAPI const char *elm_map_route_waypoint_get(const Elm_Map_Route *route
*/
EAPI Elm_Map_Name *elm_map_name_add(const Evas_Object *obj, const char *address, double lon, double lat, Elm_Map_Name_Cb name_cb, void *data);
/**
* Request a list of addresses corresponding to a given name
*
* @param obj The map object.
* @param address The address.
* @param name_cb The callback function.
* @param data The user callback data.
*
* If you want to search address from a name.
*
* @since 1.8
*
* @ingroup Map
*/
EAPI void elm_map_name_search(const Evas_Object *obj, const char *address, Elm_Map_Name_List_Cb name_cb, void *data);
/**
* Get the address of the name.
*

View File

@ -119,6 +119,7 @@ typedef struct _Elm_Map_Smart_Class
*/
typedef struct _Elm_Map_Smart_Data Elm_Map_Smart_Data;
typedef struct _Elm_Map_Name_List Elm_Map_Name_List;
typedef char *(*Elm_Map_Module_Source_Name_Func)(void);
typedef int (*Elm_Map_Module_Tile_Zoom_Min_Func)(void);
typedef int (*Elm_Map_Module_Tile_Zoom_Max_Func)(void);
@ -429,6 +430,19 @@ struct _Elm_Map_Name
void *data;
};
struct _Elm_Map_Name_List
{
Elm_Map_Smart_Data *wsd;
Eina_List *names;
double lon, lat;
char *fname;
Ecore_File_Download_Job *job;
Elm_Map_Name_List_Cb cb;
void *data;
};
struct _Route_Dump
{
int id;