2 * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
4 * Copyright (C) 2003-2005, Evan Battaglia <gtoevan@gmx.net>
5 * Copyright (C) 2009, Guilhem Bonnefille <guilhem.bonnefille@gmail.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * Created by Quy Tonthat <qtonthat@gmail.com>
33 #include <glib/gstdio.h>
34 #include <glib/gprintf.h>
35 #include <glib/gi18n.h>
39 #include "curl_download.h"
41 #include "vikxmlsearchtool.h"
44 static void vik_xml_search_tool_class_init ( VikXmlSearchToolClass *klass );
45 static void vik_xml_search_tool_init ( VikXmlSearchTool *vwd );
47 static void vik_xml_search_tool_finalize ( GObject *gob );
49 static int vik_xml_search_tool_get_coord ( VikSearchTool *self, VikWindow *vw, VikViewport *vvp, gchar *srch_str, VikCoord *coord );
51 typedef struct _VikXmlSearchToolPrivate VikXmlSearchToolPrivate;
53 struct _VikXmlSearchToolPrivate
62 #define XML_SEARCH_TOOL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
63 VIK_XML_SEARCH_TOOL_TYPE, \
64 VikXmlSearchToolPrivate))
66 GType vik_xml_search_tool_get_type()
68 static GType w_type = 0;
72 static const GTypeInfo w_info =
74 sizeof (VikXmlSearchToolClass),
76 NULL, /* base_finalize */
77 (GClassInitFunc) vik_xml_search_tool_class_init,
78 NULL, /* class_finalize */
79 NULL, /* class_data */
80 sizeof (VikXmlSearchTool),
82 (GInstanceInitFunc) vik_xml_search_tool_init,
84 w_type = g_type_register_static ( VIK_SEARCH_TOOL_TYPE, "VikXmlSearchTool", &w_info, 0 );
100 xml_search_tool_set_property (GObject *object,
105 VikXmlSearchTool *self = VIK_XML_SEARCH_TOOL (object);
106 VikXmlSearchToolPrivate *priv = XML_SEARCH_TOOL_GET_PRIVATE (self);
110 case PROP_URL_FORMAT:
111 g_free (priv->url_format);
112 priv->url_format = g_value_dup_string (value);
116 g_free (priv->lat_path);
117 priv->lat_path = g_value_dup_string (value);
121 g_free (priv->lon_path);
122 priv->lon_path = g_value_dup_string (value);
126 /* We don't have any other property... */
127 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
133 xml_search_tool_get_property (GObject *object,
138 VikXmlSearchTool *self = VIK_XML_SEARCH_TOOL (object);
139 VikXmlSearchToolPrivate *priv = XML_SEARCH_TOOL_GET_PRIVATE (self);
143 case PROP_URL_FORMAT:
144 g_value_set_string (value, priv->url_format);
148 g_value_set_string (value, priv->lat_path);
152 g_value_set_string (value, priv->lon_path);
156 /* We don't have any other property... */
157 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
162 static void vik_xml_search_tool_class_init ( VikXmlSearchToolClass *klass )
164 GObjectClass *object_class;
165 VikSearchToolClass *parent_class;
168 object_class = G_OBJECT_CLASS (klass);
170 object_class->finalize = vik_xml_search_tool_finalize;
171 object_class->set_property = xml_search_tool_set_property;
172 object_class->get_property = xml_search_tool_get_property;
175 pspec = g_param_spec_string ("url-format",
177 "The format of the URL",
178 "<no-set>" /* default value */,
179 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
180 g_object_class_install_property (object_class,
184 pspec = g_param_spec_string ("lat-path",
186 "XPath of the latitude",
187 "<no-set>" /* default value */,
188 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
189 g_object_class_install_property (object_class,
193 pspec = g_param_spec_string ("lon-path",
195 "XPath of the longitude",
196 "<no-set>" /* default value */,
197 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
198 g_object_class_install_property (object_class,
202 parent_class = VIK_SEARCH_TOOL_CLASS (klass);
204 parent_class->get_coord = vik_xml_search_tool_get_coord;
206 g_type_class_add_private (klass, sizeof (VikXmlSearchToolPrivate));
209 VikXmlSearchTool *vik_xml_search_tool_new ()
211 return VIK_XML_SEARCH_TOOL ( g_object_new ( VIK_XML_SEARCH_TOOL_TYPE, "label", "Google", NULL ) );
214 static void vik_xml_search_tool_init ( VikXmlSearchTool *self )
216 VikXmlSearchToolPrivate *priv = XML_SEARCH_TOOL_GET_PRIVATE (self);
217 priv->url_format = NULL;
218 priv->lat_path = NULL;
219 priv->lon_path = NULL;
225 static void vik_xml_search_tool_finalize ( GObject *gob )
227 G_OBJECT_GET_CLASS(gob)->finalize(gob);
231 stack_is_path (const GSList *stack,
234 gboolean equal = TRUE;
235 int stack_len = g_list_length(stack);
238 while (equal == TRUE && i >= 0)
244 const gchar *current = g_list_nth_data(stack, i);
245 size_t len = strlen(current);
246 if (strncmp(path, current, len) != 0 )
259 /* Called for character data */
260 /* text is not nul-terminated */
262 _text (GMarkupParseContext *context,
268 VikXmlSearchTool *self = VIK_XML_SEARCH_TOOL (user_data);
269 VikXmlSearchToolPrivate *priv = XML_SEARCH_TOOL_GET_PRIVATE (self);
270 const GSList *stack = g_markup_parse_context_get_element_stack (context);
271 gchar *textl = g_strndup(text, text_len);
272 if (stack_is_path (stack, priv->lat_path))
274 priv->ll.lat = g_ascii_strtod(textl, NULL);
276 if (stack_is_path (stack, priv->lon_path))
278 priv->ll.lon = g_ascii_strtod(textl, NULL);
284 parse_file_for_latlon(VikXmlSearchTool *self, gchar *filename, struct LatLon *ll)
286 GMarkupParser xml_parser;
287 GMarkupParseContext *xml_context;
289 VikXmlSearchToolPrivate *priv = XML_SEARCH_TOOL_GET_PRIVATE (self);
291 FILE *file = g_fopen (filename, "r");
293 /* TODO emit warning */
296 /* setup context parse (ie callbacks) */
297 xml_parser.start_element = NULL;
298 xml_parser.end_element = NULL;
299 xml_parser.text = &_text;
300 xml_parser.passthrough = NULL;
301 xml_parser.error = NULL;
303 xml_context = g_markup_parse_context_new(&xml_parser, 0, self, NULL);
311 while ((nb = fread (buff, sizeof(gchar), BUFSIZ, file)) > 0)
313 if (!g_markup_parse_context_parse(xml_context, buff, nb, &error))
314 printf("read_xml() : parsing error.\n");
317 if (!g_markup_parse_context_end_parse(xml_context, &error))
318 printf("read_xml() : errors occurred reading file.\n");
320 g_markup_parse_context_free(xml_context);
328 if (isnan(priv->ll.lat) || isnan(priv->ll.lat))
329 /* At least one coordinate not found */
335 static int vik_xml_search_tool_get_coord ( VikSearchTool *object, VikWindow *vw, VikViewport *vvp, gchar *srch_str, VikCoord *coord )
341 gchar *escaped_srch_str;
342 int ret = 0; /* OK */
345 g_debug("%s: raw search: %s", __FUNCTION__, srch_str);
347 escaped_srch_str = uri_escape(srch_str);
349 g_debug("%s: escaped search: %s", __FUNCTION__, escaped_srch_str);
351 if ((tmp_fd = g_file_open_tmp ("vikxmlsearch.XXXXXX", &tmpname, NULL)) == -1) {
352 g_critical(_("couldn't open temp file"));
356 VikXmlSearchTool *self = VIK_XML_SEARCH_TOOL (object);
357 VikXmlSearchToolPrivate *priv = XML_SEARCH_TOOL_GET_PRIVATE (self);
359 tmp_file = fdopen(tmp_fd, "r+");
360 uri = g_strdup_printf(priv->url_format, escaped_srch_str);
362 /* TODO: curl may not be available */
363 if (curl_download_uri(uri, tmp_file, NULL)) { /* error */
372 g_debug("%s: %s", __FILE__, tmpname);
373 if (!parse_file_for_latlon(self, tmpname, &ll)) {
377 vik_coord_load_from_latlon ( coord, vik_viewport_get_coord_mode(vvp), &ll );
380 g_free(escaped_srch_str);