3 #include <libgnomevfs/gnome-vfs.h>
11 #include "mapper-types.h"
12 #include "ui-common.h"
21 struct sql_select_stmt {
22 sqlite3_stmt *select_track;
23 sqlite3_stmt *select_track_nodes;
24 sqlite3_stmt *insert_track;
25 sqlite3_stmt *insert_track_node;
26 sqlite3_stmt *delete_track_nodes;
27 sqlite3_stmt *delete_track;
29 static struct sql_select_stmt sql;
34 memset(&_track, 0, sizeof(_track));
35 MACRO_PATH_INIT(_track);
41 MACRO_PATH_FREE(_track);
49 confirm = hildon_note_new_confirmation(GTK_WINDOW(_window), _("Clear the track?"));
51 if (GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm))) {
52 _track.tail = _track.head;
55 gtk_widget_destroy(confirm);
59 track_calculate_distance_from(Point *point)
61 gdouble lat1, lon1, lat2, lon2;
64 unit2latlon(_gps->data.unitx, _gps->data.unity, lat1, lon1);
66 /* Skip _track.tail because that should be _gps. */
67 for (curr = _track.tail; curr > point; --curr) {
69 unit2latlon(curr->unitx, curr->unity, lat2, lon2);
70 sum += calculate_distance(lat1, lon1, lat2, lon2);
79 track_show_distance_from(Point * point)
84 sum = track_calculate_distance_from(point);
86 g_snprintf(buffer, sizeof(buffer), "%s: %.02f %s", _("Distance"),
87 sum * UNITS_CONVERT[_units], UNITS_TEXT[_units]);
88 MACRO_BANNER_SHOW_INFO(_window, buffer);
92 track_show_distance_from_last()
94 /* Find last zero point. */
95 if (_track.head != _track.tail) {
97 /* Find last zero point. */
98 for (point = _track.tail; point->unity; point--) {
100 track_show_distance_from(point);
102 MACRO_BANNER_SHOW_INFO(_window, _("The current track is empty."));
107 track_show_distance_from_first()
109 if (_track.head != _track.tail) {
110 track_show_distance_from(_track.head);
112 MACRO_BANNER_SHOW_INFO(_window, _("The current track is empty."));
117 * Add a point to the _track list. This function is slightly overloaded,
118 * since it is what houses the check for "have we moved
119 * significantly": it also initiates the re-calculation of the _near_point
120 * data, as well as calling osso_display_state_on() when we have the focus.
122 * If a non-zero time is given, then the current position (as taken from the
123 * _gps variable) is appended to _track with the given time. If time is zero,
124 * then _point_null is appended to _track with time zero (this produces a "break"
128 track_add(GpsData *gps)
130 gboolean show_directions = TRUE;
131 gint announce_thres_unsquared;
134 MACRO_PATH_INCREMENT_TAIL(_track);
135 *_track.tail=_point_null;
139 if (abs((gint)gps->unitx-_track.tail->unitx) > _draw_width || abs((gint)gps->unity-_track.tail->unity) > _draw_width) {
141 /* If gps is available, update the nearest-waypoint data. */
142 if (gps && _route.head != _route.tail && (gps->newly_fixed ? (route_find_nearest_point(), TRUE) : route_update_nears(TRUE))) {
143 /* Nearest waypoint has changed - re-render paths. */
145 MACRO_QUEUE_DRAW_AREA();
148 if (_show_tracks & TRACKS_MASK) {
149 gint tx1, ty1, tx2, ty2;
151 /* Instead of calling map_render_paths(), we'll draw the new line
152 * ourselves and call gtk_widget_queue_draw_area(). */
153 map_render_segment(_gc[COLORABLE_TRACK], _gc[COLORABLE_TRACK_BREAK],
154 _track.tail->unitx, _track.tail->unity, gps->unitx, gps->unity);
156 if (_track.tail->unity && _track.tail->unitx) {
157 tx1 = unit2x(_track.tail->unitx);
158 ty1 = unit2y(_track.tail->unity);
159 tx2 = unit2x(gps->unitx);
160 ty2 = unit2y(gps->unity);
161 gtk_widget_queue_draw_area(_map_widget,
162 MIN(tx1, tx2) - _draw_width,
163 MIN(ty1, ty2) - _draw_width,
164 abs(tx1 - tx2) + (2 * _draw_width),
165 abs(ty1 - ty2) + (2 * _draw_width));
169 MACRO_PATH_INCREMENT_TAIL(_track);
170 _track.tail->unitx=gps->unitx;
171 _track.tail->unity=gps->unity;
172 _track.tail->time=gps->time;
173 _track.tail->altitude=gps->altitude;
176 if (_autoroute_data.enabled && !_autoroute_data.in_progress && _near_point_dist_squared > 400) {
177 MACRO_BANNER_SHOW_INFO(_window, _("Recalculating directions..."));
178 _autoroute_data.in_progress = TRUE;
179 show_directions = FALSE;
180 g_idle_add((GSourceFunc)auto_route_dl_idle, NULL);
183 announce_thres_unsquared=(20+(guint)gps->speed)*_announce_notice_ratio*3;
185 /* Check if we should announce upcoming waypoints. */
186 if (gps && show_directions && _next_way_dist_squared < (announce_thres_unsquared * announce_thres_unsquared)) {
187 if (_enable_voice && strcmp(_next_way->desc, _last_spoken_phrase)) {
188 g_free(_last_spoken_phrase);
189 _last_spoken_phrase=g_strdup(_next_way->desc);
190 speak_text(_last_spoken_phrase);
192 MACRO_BANNER_SHOW_INFO(_window, _next_way->desc);
195 /* Keep the display on if we are moving. */
200 track_insert_break(void)
202 if (_track.tail->unity) {
205 /* To mark a "waypoint" in a track, we'll add a (0, 0) point and then
206 * another instance of the most recent track point. */
207 MACRO_PATH_INCREMENT_TAIL(_track);
208 *_track.tail=_point_null;
209 MACRO_PATH_INCREMENT_TAIL(_track);
210 *_track.tail=_track.tail[-2];
212 /* Instead of calling map_render_paths(), we'll just draw the waypoint ourselves. */
213 x1 = unit2bufx(_track.tail->unitx);
214 y1 = unit2bufy(_track.tail->unity);
215 map_render_waypoint(x1, y1, _gc[COLORABLE_TRACK_BREAK]);
227 if (file_open_get_contents(&_track_file_uri, &buffer, &size)) {
228 if (parse_gpx(&_track, buffer, size, -1)) {
230 MACRO_BANNER_SHOW_INFO(_window, _("Track Opened"));
233 popup_error(_window, _("Error parsing GPX file."));
243 GnomeVFSHandle *handle;
246 if (file_save(&_track_file_uri, &_track_file_uri, &handle)) {
247 if (write_gpx(&_track, handle)) {
248 MACRO_BANNER_SHOW_INFO(_window, _("Track Saved"));
252 popup_error(_window, _("Error writing GPX file."));
254 gnome_vfs_close(handle);
260 * Add a text description at current point
264 track_insert_mark_text(gchar *text)
266 MACRO_PATH_INCREMENT_WTAIL(_track);
267 _track.wtail->point = _track.tail;
268 _track.wtail->desc = text;
272 * Ask for a text description for the current point
276 track_insert_mark(void)
279 gchar tmp1[16], tmp2[16], *p_latlon;
283 GtkWidget *txt_scroll;
286 dialog = gtk_dialog_new_with_buttons(_("Insert Mark"),
288 GTK_DIALOG_MODAL, GTK_STOCK_OK,
291 GTK_RESPONSE_REJECT, NULL);
293 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), table = gtk_table_new(2, 2, FALSE), TRUE, TRUE, 0);
295 gtk_table_attach(GTK_TABLE(table), label = gtk_label_new(_("Lat, Lon")), 0, 1, 0, 1, GTK_FILL, 0, 2, 4);
296 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
298 unit2latlon(_gps->data.unitx, _gps->data.unity, lat, lon);
299 lat_format(_degformat, lat, tmp1);
300 lon_format(_degformat, lon, tmp2);
301 p_latlon = g_strdup_printf("%s, %s", tmp1, tmp2);
302 gtk_table_attach(GTK_TABLE(table), label = gtk_label_new(p_latlon), 1, 2, 0, 1, GTK_FILL, 0, 2, 4);
303 gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
306 gtk_table_attach(GTK_TABLE(table), label = gtk_label_new(_("Description")), 0, 1, 1, 2, GTK_FILL, 0, 2, 4);
307 gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
309 txt_scroll = gtk_scrolled_window_new(NULL, NULL);
310 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(txt_scroll), GTK_SHADOW_IN);
311 gtk_table_attach(GTK_TABLE(table), txt_scroll, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
313 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
315 txt_desc = gtk_text_view_new();
316 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt_desc), GTK_WRAP_WORD);
318 gtk_container_add(GTK_CONTAINER(txt_scroll), txt_desc);
319 gtk_widget_set_size_request(GTK_WIDGET(txt_scroll), 450, 80);
321 gtk_widget_show_all(dialog);
323 while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog))) {
325 GtkTextIter ti1, ti2;
327 tbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txt_desc));
328 gtk_text_buffer_get_iter_at_offset(tbuf, &ti1, 0);
329 gtk_text_buffer_get_end_iter(tbuf, &ti2);
331 if (gtk_text_buffer_get_char_count(tbuf)>0) {
332 track_insert_mark_text(gtk_text_buffer_get_text(tbuf, &ti1, &ti2, TRUE));
334 popup_error(dialog, _("Please provide a description for the mark."));
339 MACRO_QUEUE_DRAW_AREA();
342 gtk_widget_destroy(dialog);