#define GCONF_KEY_REPOSITORIES GCONF_KEY_PREFIX"/repositories"
#define GCONF_KEY_CURRREPO GCONF_KEY_PREFIX"/curr_repo"
#define GCONF_KEY_GPS_INFO GCONF_KEY_PREFIX"/gps_info"
+#define GCONF_KEY_ROUTE_DL_RADIUS GCONF_KEY_PREFIX"/route_dl_radius"
+
#define GCONF_KEY_DISCONNECT_ON_COVER "/system/osso/connectivity/IAP/disconnect_on_cover"
+#define CONFIG_DIR_NAME "~/.maemo-mapper/"
+#define CONFIG_FILE_ROUTE "route.gpx"
+#define CONFIG_FILE_TRACK "track.gpx"
#define XML_DATE_FORMAT "%FT%T"
} \
}
+#define MACRO_TRACK_INCREMENT_TAIL(track) { \
+ if(++(track).tail == (track).cap) \
+ track_resize(&(track), (track).cap - (track).head + ARRAY_CHUNK_SIZE); \
+}
+
+#define MACRO_ROUTE_INCREMENT_TAIL(route) { \
+ if(++(route).tail == (route).cap) \
+ route_resize(&(route), (route).cap - (route).head + ARRAY_CHUNK_SIZE); \
+}
+
+#define MACRO_ROUTE_INCREMENT_WTAIL(route) { \
+ if(++(route).wtail == (route).wcap) \
+ route_wresize(&(route), \
+ (route).wcap - (route).whead + ARRAY_CHUNK_SIZE); \
+}
+
#define TRACKS_MASK 0x00000001
#define ROUTES_MASK 0x00000002
static gboolean _fullscreen = FALSE;
static gboolean _enable_gps = FALSE;
static gboolean _gps_info = FALSE;
+static guint _route_dl_radius = 4;
static gint _show_tracks = 0;
static gboolean _show_velvec = TRUE;
static gboolean _auto_download = FALSE;
static UnitType _units = UNITS_KM;
static EscapeKeyAction _escape_key = ESCAPE_KEY_TOGGLE_TRACKS;
+static gchar *_config_dir_uri;
+
static GList *_repo_list = NULL;
static RepoData *_curr_repo = NULL;
* ABOVE: CALLBACK DECLARATIONS *********************************************
****************************************************************************/
+/**
+ * Pop up a modal dialog box with simple error information in it.
+ */
+static void
+popup_error(GtkWidget *window, const gchar *error)
+{
+ GtkWidget *dialog;
+ printf("%s(\"%s\")\n", __PRETTY_FUNCTION__, error);
+ dialog = hildon_note_new_information(GTK_WINDOW(window), error);
-/****************************************************************************
- * BELOW: ROUTINES **********************************************************
- ****************************************************************************/
+ gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_destroy(dialog);
-static gboolean
-gps_display_details(void)
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+static void
+track_resize(Track *track, guint size)
{
- gchar *buffer, strtime[15];
printf("%s()\n", __PRETTY_FUNCTION__);
- if(_gps.fix < 2)
+ if(track->head + size != track->cap)
{
- /* no fix no fun */
- gtk_label_set_label(GTK_LABEL(_sdi_lat), " --- ");
- gtk_label_set_label(GTK_LABEL(_sdi_lon), " --- ");
- gtk_label_set_label(GTK_LABEL(_sdi_spd), " --- ");
- gtk_label_set_label(GTK_LABEL(_sdi_alt), " --- ");
- gtk_label_set_label(GTK_LABEL(_sdi_hea), " --- ");
- gtk_label_set_label(GTK_LABEL(_sdi_tim), " --:--:-- ");
+ TrackPoint *old_head = track->head;
+ track->head = g_renew(TrackPoint, old_head, size);
+ track->cap = track->head + size;
+ if(track->head != old_head)
+ track->tail = track->head + (track->tail - old_head);
}
- else
- {
- gfloat speed = _gps.speed * UNITS_CONVERT[_units];
- /* latitude */
- gtk_label_set_label(GTK_LABEL(_sdi_lat), _gps.slatitude);
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
- /* longitude */
- gtk_label_set_label(GTK_LABEL(_sdi_lon), _gps.slongitude);
+static void
+route_resize(Route *route, guint size)
+{
+ printf("%s()\n", __PRETTY_FUNCTION__);
- /* speed */
- switch(_units)
+ if(route->head + size != route->cap)
+ {
+ Point *old_head = route->head;
+ WayPoint *curr;
+ route->head = g_renew(Point, old_head, size);
+ route->cap = route->head + size;
+ if(route->head != old_head)
{
- case UNITS_MI:
- buffer = g_strdup_printf("%.1f mph", speed);
- break;
- case UNITS_NM:
- buffer = g_strdup_printf("%.1f kn", speed);
- break;
- default:
- buffer = g_strdup_printf("%.1f km/h", speed);
- break;
- }
- gtk_label_set_label(GTK_LABEL(_sdi_spd), buffer);
- g_free(buffer);
+ route->tail = route->head + (route->tail - old_head);
- /* altitude */
- switch(_units)
- {
- case UNITS_MI:
- case UNITS_NM:
- buffer = g_strdup_printf("%d ft",
- (guint)(_gps.altitude * 3.2808399f));
- break;
- default:
- buffer = g_strdup_printf("%d m", _gps.altitude);
- break;
+ /* Adjust all of the waypoints. */
+ for(curr = route->whead - 1; curr++ != route->wtail; )
+ curr->point = route->head + (curr->point - old_head);
}
- gtk_label_set_label(GTK_LABEL(_sdi_alt), buffer);
- g_free(buffer);
-
- /* heading */
- buffer = g_strdup_printf("%0.0f\u00b0", _gps.heading);
- gtk_label_set_label(GTK_LABEL(_sdi_hea), buffer);
- g_free(buffer);
-
- /* local time */
- strftime(strtime, 15, "%X", &_gps.timeloc);
- gtk_label_set_label(GTK_LABEL(_sdi_tim), strtime);
}
- /* Sat in view */
- buffer = g_strdup_printf("%d", _gps.satinview);
- gtk_label_set_label(GTK_LABEL(_sdi_vie), buffer);
- g_free(buffer);
-
- /* Sat in use */
- buffer = g_strdup_printf("%d", _gps.satinuse);
- gtk_label_set_label(GTK_LABEL(_sdi_use), buffer);
- g_free(buffer);
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
- /* fix */
- switch(_gps.fix)
- {
- case 2:
- case 3: buffer = g_strdup_printf("%dD fix", _gps.fix); break;
- default: buffer = g_strdup_printf("nofix"); break;
- }
- gtk_label_set_label(GTK_LABEL(_sdi_fix), buffer);
- g_free(buffer);
+static void
+route_wresize(Route *route, guint wsize)
+{
+ printf("%s()\n", __PRETTY_FUNCTION__);
- if(_gps.fix == 1)
- buffer = g_strdup("none");
- else
+ if(route->whead + wsize != route->wcap)
{
- switch (_gps.fixquality)
- {
- case 1 : buffer = g_strdup_printf(_("SPS")); break;
- case 2 : buffer = g_strdup_printf(_("DGPS")); break;
- case 3 : buffer = g_strdup_printf(_("PPS")); break;
- case 4 : buffer = g_strdup_printf(_("Real Time Kinematic")); break;
- case 5 : buffer = g_strdup_printf(_("Float RTK")); break;
- case 6 : buffer = g_strdup_printf(_("Estimated")); break;
- case 7 : buffer = g_strdup_printf(_("Manual)")); break;
- case 8 : buffer = g_strdup_printf(_("Simulation")); break;
- default : buffer = g_strdup_printf(_("none")); break;
- }
+ WayPoint *old_whead = route->whead;
+ route->whead = g_renew(WayPoint, old_whead, wsize);
+ route->wtail = route->whead + (route->wtail - old_whead);
+ route->wcap = route->whead + wsize;
}
- gtk_label_set_label(GTK_LABEL(_sdi_fqu), buffer);
- g_free(buffer);
- /* max speed */
- {
- gfloat maxspeed = _gps.maxspeed * UNITS_CONVERT[_units];
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
- /* speed */
- switch(_units)
- {
- case UNITS_MI:
- buffer = g_strdup_printf("%.1f mph", maxspeed);
- break;
- case UNITS_NM:
- buffer = g_strdup_printf("%.1f kn", maxspeed);
- break;
- default:
- buffer = g_strdup_printf("%.1f km/h", maxspeed);
- break;
- }
- gtk_label_set_label(GTK_LABEL(_sdi_msp), buffer);
- g_free(buffer);
- }
- /* refresh sat panel */
- gtk_widget_queue_draw_area(GTK_WIDGET(_sat_details_panel),
- 0, 0,
- _sat_details_panel->allocation.width,
- _sat_details_panel->allocation.height);
+/****************************************************************************
+ * BELOW: FILE-HANDLING ROUTINES *********************************************
+ ****************************************************************************/
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
- return TRUE;
+#define WRITE_STRING(string) { \
+ GnomeVFSResult vfs_result; \
+ GnomeVFSFileSize size; \
+ if(GNOME_VFS_OK != (vfs_result = gnome_vfs_write( \
+ handle, (string), strlen((string)), &size))) \
+ { \
+ gchar buffer[1024]; \
+ sprintf(buffer, "%s:\n%s\n%s", _("Error while writing to file"), \
+ _("File is incomplete."), \
+ gnome_vfs_result_to_string(vfs_result)); \
+ popup_error(_window, buffer); \
+ return FALSE; \
+ } \
}
-static void
-gps_display_data(void)
+static gboolean
+write_track_gpx(GnomeVFSHandle *handle)
{
- gchar *buffer, strtime[15];
+ TrackPoint *curr;
+ gboolean trkseg_break = FALSE;
printf("%s()\n", __PRETTY_FUNCTION__);
- if(_gps.fix < 2)
- {
- /* no fix no fun */
- gtk_label_set_label(GTK_LABEL(_text_lat), " --- ");
- gtk_label_set_label(GTK_LABEL(_text_lon), " --- ");
- gtk_label_set_label(GTK_LABEL(_text_speed), " --- ");
- gtk_label_set_label(GTK_LABEL(_text_alt), " --- ");
- gtk_label_set_label(GTK_LABEL(_text_time), " --:--:-- ");
- }
- else
- {
- gfloat speed = _gps.speed * UNITS_CONVERT[_units];
-
- /* latitude */
- gtk_label_set_label(GTK_LABEL(_text_lat), _gps.slatitude);
-
- /* longitude */
- gtk_label_set_label(GTK_LABEL(_text_lon), _gps.slongitude);
+ /* Find first non-zero point. */
+ for(curr = _track.head-1; curr++ != _track.tail; )
+ if(curr->point.unity)
+ break;
- /* speed */
- switch(_units)
- {
- case UNITS_MI:
- buffer = g_strdup_printf("Spd: %.1f mph", speed);
- break;
- case UNITS_NM:
- buffer = g_strdup_printf("Spd: %.1f kn", speed);
- break;
- default:
- buffer = g_strdup_printf("Spd: %.1f km/h", speed);
- break;
- }
- gtk_label_set_label(GTK_LABEL(_text_speed), buffer);
- g_free(buffer);
+ /* Write the header. */
+ WRITE_STRING(XML_TRKSEG_HEADER);
- /* altitude */
- switch(_units)
+ /* Curr points to first non-zero point. */
+ for(curr--; curr++ != _track.tail; )
+ {
+ gfloat lat, lon;
+ if(curr->point.unity)
{
- case UNITS_MI:
- case UNITS_NM:
- buffer = g_strdup_printf("Alt: %d ft",
- (guint)(_gps.altitude * 3.2808399f));
- break;
- default:
- buffer = g_strdup_printf("Alt: %d m", _gps.altitude);
- }
- gtk_label_set_label(GTK_LABEL(_text_alt), buffer);
- g_free(buffer);
+ gchar buffer[80];
+ gchar strlat[80], strlon[80];
+ if(trkseg_break)
+ {
+ /* First trkpt of the segment - write trkseg header. */
+ WRITE_STRING(" </trkseg>\n"
+ /* Write trkseg header. */
+ " <trkseg>\n");
+ trkseg_break = FALSE;
+ }
+ unit2latlon(curr->point.unitx, curr->point.unity, lat, lon);
+ g_ascii_formatd(strlat, 80, "%.06f", lat);
+ g_ascii_formatd(strlon, 80, "%.06f", lon);
+ sprintf(buffer, " <trkpt lat=\"%s\" lon=\"%s\"",
+ strlat, strlon);
+ WRITE_STRING(buffer);
- /* local time */
- strftime(strtime, 15, "%X", &_gps.timeloc);
- gtk_label_set_label(GTK_LABEL(_text_time), strtime);
+ /* write the time */
+ if(curr->time)
+ {
+ WRITE_STRING(">\n <time>");
+ {
+ struct tm time;
+ localtime_r(&curr->time, &time);
+ strftime(buffer, 80, XML_DATE_FORMAT, &time);
+ WRITE_STRING(buffer);
+ WRITE_STRING(XML_TZONE);
+ }
+ WRITE_STRING("</time>\n"
+ " </trkpt>\n");
+ }
+ else
+ WRITE_STRING("/>\n");
+ }
+ else
+ trkseg_break = TRUE;
}
- /* refresh sat panel */
- gtk_widget_queue_draw_area(GTK_WIDGET(_sat_panel),
- 0, 0,
- _sat_panel->allocation.width,
- _sat_panel->allocation.height);
-
- /* refresh heading panel*/
- gtk_widget_queue_draw_area(GTK_WIDGET(_heading_panel),
- 0, 0,
- _heading_panel->allocation.width,
- _heading_panel->allocation.height);
+ /* Write the footer. */
+ WRITE_STRING(XML_TRKSEG_FOOTER);
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
- return;
+ vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+ return TRUE;
}
-static void
-gps_hide_text(void)
+static gboolean
+write_route_gpx(GnomeVFSHandle *handle)
{
- printf("%s()\n", __PRETTY_FUNCTION__);
+ Point *curr;
+ WayPoint *wcurr;
+ gboolean trkseg_break = FALSE;
- /* Clear gps data */
- _gps.fix = 1;
- _gps.satinuse = 0;
- _gps.satinview = 0;
+ /* Find first non-zero point. */
+ if(_route.head)
+ for(curr = _route.head-1, wcurr = _route.whead; curr++ != _route.tail; )
+ {
+ if(curr->unity)
+ break;
+ else if(wcurr && curr == wcurr->point)
+ wcurr++;
+ }
- if(_gps_info)
- gps_display_data();
+ /* Write the header. */
+ WRITE_STRING(XML_TRKSEG_HEADER);
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+ /* Curr points to first non-zero point. */
+ if(_route.head)
+ for(curr--; curr++ != _route.tail; )
+ {
+ gfloat lat, lon;
+ if(curr->unity)
+ {
+ gchar buffer[80];
+ gchar strlat[80], strlon[80];
+ if(trkseg_break)
+ {
+ /* First trkpt of the segment - write trkseg header. */
+ WRITE_STRING(" </trkseg>\n"
+ " <trkseg>\n");
+ trkseg_break = FALSE;
+ }
+ unit2latlon(curr->unitx, curr->unity, lat, lon);
+ g_ascii_formatd(strlat, 80, "%.06f", lat);
+ g_ascii_formatd(strlon, 80, "%.06f", lon);
+ sprintf(buffer, " <trkpt lat=\"%s\" lon=\"%s\"",
+ strlat, strlon);
+ if(wcurr && curr == wcurr->point)
+ sprintf(buffer + strlen(buffer),
+ "><desc>%s</desc></trkpt>\n", wcurr++->desc);
+ else
+ strcat(buffer, "/>\n");
+ WRITE_STRING(buffer);
+ }
+ else
+ trkseg_break = TRUE;
+ }
+
+ /* Write the footer. */
+ WRITE_STRING(XML_TRKSEG_FOOTER);
+
+ vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+ return TRUE;
}
+/**
+ * Handle a start tag in the parsing of a GPX file.
+ */
+#define MACRO_SET_UNKNOWN() { \
+ data->prev_state = data->state; \
+ data->state = UNKNOWN; \
+ data->unknown_depth = 1; \
+}
static void
-gps_show_info(void)
+gpx_start_element(SaxData *data, const xmlChar *name, const xmlChar **attrs)
{
- printf("%s()\n", __PRETTY_FUNCTION__);
+ vprintf("%s(%s)\n", __PRETTY_FUNCTION__, name);
- if(_gps_info && _enable_gps)
- gtk_widget_show_all(GTK_WIDGET(_gps_widget));
- else
+ switch(data->state)
{
- gps_hide_text();
- gtk_widget_hide_all(GTK_WIDGET(_gps_widget));
+ case ERROR:
+ break;
+ case START:
+ if(!strcmp((gchar*)name, "gpx"))
+ data->state = INSIDE_GPX;
+ else
+ MACRO_SET_UNKNOWN();
+ break;
+ case INSIDE_GPX:
+ if(!strcmp((gchar*)name, "trk"))
+ data->state = INSIDE_PATH;
+ else
+ MACRO_SET_UNKNOWN();
+ break;
+ case INSIDE_PATH:
+ if(!strcmp((gchar*)name, "trkseg"))
+ {
+ data->state = INSIDE_PATH_SEGMENT;
+ data->at_least_one_trkpt = FALSE;
+ }
+ else
+ MACRO_SET_UNKNOWN();
+ break;
+ case INSIDE_PATH_SEGMENT:
+ if(!strcmp((gchar*)name, "trkpt"))
+ {
+ const xmlChar **curr_attr;
+ gchar *error_check;
+ gfloat lat = 0.f, lon = 0.f;
+ gboolean has_lat, has_lon;
+ has_lat = FALSE;
+ has_lon = FALSE;
+ for(curr_attr = attrs; *curr_attr != NULL; )
+ {
+ const gchar *attr_name = *curr_attr++;
+ const gchar *attr_val = *curr_attr++;
+ if(!strcmp(attr_name, "lat"))
+ {
+ lat = g_ascii_strtod(attr_val, &error_check);
+ if(error_check != attr_val)
+ has_lat = TRUE;
+ }
+ else if(!strcmp(attr_name, "lon"))
+ {
+ lon = g_ascii_strtod(attr_val, &error_check);
+ if(error_check != attr_val)
+ has_lon = TRUE;
+ }
+ }
+ if(has_lat && has_lon)
+ {
+ if(data->path.path_type == TRACK)
+ {
+ MACRO_TRACK_INCREMENT_TAIL(data->path.path.track);
+ latlon2unit(lat, lon,
+ data->path.path.track.tail->point.unitx,
+ data->path.path.track.tail->point.unity);
+ data->path.path.track.tail->time = 0;
+ }
+ else
+ {
+ MACRO_ROUTE_INCREMENT_TAIL(data->path.path.route);
+ latlon2unit(lat, lon,
+ data->path.path.route.tail->unitx,
+ data->path.path.route.tail->unity);
+ }
+ data->state = INSIDE_PATH_POINT;
+ }
+ else
+ data->state = ERROR;
+ }
+ else
+ MACRO_SET_UNKNOWN();
+ break;
+ case INSIDE_PATH_POINT:
+ /* only parse time for tracks */
+ if(data->path.path_type == TRACK
+ && !strcmp((gchar*)name, "time"))
+ data->state = INSIDE_PATH_POINT_TIME;
+
+ /* only parse description for routes */
+ else if(data->path.path_type == ROUTE
+ && !strcmp((gchar*)name, "desc"))
+ data->state = INSIDE_PATH_POINT_DESC;
+
+ else
+ MACRO_SET_UNKNOWN();
+ break;
+ case UNKNOWN:
+ data->unknown_depth++;
+ break;
+ default:
+ ;
}
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
+/**
+ * Handle an end tag in the parsing of a GPX file.
+ */
static void
-draw_sat_info(GtkWidget *widget, guint x0, guint y0,
- guint width, guint height, gboolean showsnr)
+gpx_end_element(SaxData *data, const xmlChar *name)
{
- PangoContext *context = NULL;
- PangoLayout *layout = NULL;
- PangoFontDescription *fontdesc = NULL;
- GdkColor color;
- GdkGC *gc1, *gc2, *gc;
- guint step, i, j, snr_height, bymargin, xoffset, yoffset;
- guint x, y, x1, y1;
- gchar *tmp = NULL;
-
- xoffset = x0;
- yoffset = y0;
- /* Bootom margin - 12% */
- bymargin = height * 0.88f;
-
- /* Bottom line */
- gdk_draw_line(widget->window,
- widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
- xoffset + 5, yoffset + bymargin,
- xoffset + width - 10 - 2, yoffset + bymargin);
- gdk_draw_line(widget->window,
- widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
- xoffset + 5, yoffset + bymargin - 1,
- xoffset + width - 10 - 2, yoffset + bymargin - 1);
-
- context = gtk_widget_get_pango_context(widget);
- layout = pango_layout_new(context);
- fontdesc = pango_font_description_new();
-
- pango_font_description_set_family(fontdesc,"Sans Serif");
+ vprintf("%s(%s)\n", __PRETTY_FUNCTION__, name);
- if(_gps.satinview > 0 )
+ switch(data->state)
{
- pango_font_description_set_size(fontdesc, 8*PANGO_SCALE);
-
- pango_layout_set_font_description (layout, fontdesc);
- pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
-
- /* Left margin - 5pix, Right margin - 5pix */
- step = (width - 10) / _gps.satinview;
-
- color.red = 0;
- color.green = 0;
- color.blue = 0;
- gc1 = gdk_gc_new (widget->window);
- gdk_gc_set_rgb_fg_color (gc1, &color);
-
- color.red = 0;
- color.green = 0;
- color.blue = 0xffff;
- gc2 = gdk_gc_new (widget->window);
- gdk_gc_set_rgb_fg_color (gc2, &color);
-
- for(i = 0; i < _gps.satinview; i++)
- {
- /* Sat used or not */
- gc = gc1;
- for(j = 0; j < _gps.satinuse ; j++)
+ case ERROR:
+ break;
+ case START:
+ data->state = ERROR;
+ break;
+ case INSIDE_GPX:
+ if(!strcmp((gchar*)name, "gpx"))
+ data->state = FINISH;
+ else
+ data->state = ERROR;
+ break;
+ case INSIDE_PATH:
+ if(!strcmp((gchar*)name, "trk"))
+ data->state = INSIDE_GPX;
+ else
+ data->state = ERROR;
+ break;
+ case INSIDE_PATH_SEGMENT:
+ if(!strcmp((gchar*)name, "trkseg"))
{
- if(_gps.satforfix[j] == _gps_sat[i].prn)
+ if(data->at_least_one_trkpt)
{
- gc = gc2;
- break;
+ if(data->path.path_type == TRACK)
+ {
+ MACRO_TRACK_INCREMENT_TAIL(data->path.path.track);
+ *data->path.path.track.tail = _track_null;
+ }
+ else
+ {
+ MACRO_ROUTE_INCREMENT_TAIL(data->path.path.route);
+ *data->path.path.route.tail = _pos_null;
+ }
}
+ data->state = INSIDE_PATH;
+ }
+ else
+ data->state = ERROR;
+ break;
+ case INSIDE_PATH_POINT:
+ if(!strcmp((gchar*)name, "trkpt"))
+ {
+ data->state = INSIDE_PATH_SEGMENT;
+ data->at_least_one_trkpt = TRUE;
}
+ else
+ data->state = ERROR;
+ break;
+ case INSIDE_PATH_POINT_TIME:
+ /* only parse time for tracks */
+ if(!strcmp((gchar*)name, "time"))
+ {
+ struct tm time;
+ gchar *ptr;
- x = 5 + i * step;
- snr_height = _gps_sat[i].snr * height * 0.78f / 100;
- y = height * 0.1f + (height * 0.78f - snr_height);
+ if(NULL == (ptr = strptime(data->chars->str,
+ XML_DATE_FORMAT, &time)))
+ /* Failed to parse dateTime format. */
+ data->state = ERROR;
+ else
+ {
+ /* Parse was successful. Now we have to parse timezone.
+ * From here on, if there is an error, I just assume local
+ * timezone. Yes, this is not proper XML, but I don't
+ * care. */
+ gchar *error_check;
- /* draw sat rectangle... */
- gdk_draw_rectangle(widget->window,
- gc,
- TRUE,
- xoffset + x,
- yoffset + y,
- step - 2,
- snr_height);
+ /* First, set time in "local" time zone. */
+ data->path.path.track.tail->time = (mktime(&time));
- if(showsnr && _gps_sat[i].snr > 0)
+ /* Now, skip inconsequential characters */
+ while(*ptr && *ptr != 'Z' && *ptr != '-' && *ptr != '+')
+ ptr++;
+
+ /* Check if we ran to the end of the string. */
+ if(*ptr)
+ {
+ /* Next character is either 'Z', '-', or '+' */
+ if(*ptr == 'Z')
+ /* Zulu (UTC) time. Undo the local time zone's
+ * offset. */
+ data->path.path.track.tail->time += time.tm_gmtoff;
+ else
+ {
+ /* Not Zulu (UTC). Must parse hours and minutes. */
+ gint offhours = strtol(ptr, &error_check, 10);
+ if(error_check != ptr
+ && *(ptr = error_check) == ':')
+ {
+ /* Parse of hours worked. Check minutes. */
+ gint offmins = strtol(ptr + 1,
+ &error_check, 10);
+ if(error_check != (ptr + 1))
+ {
+ /* Parse of minutes worked. Calculate. */
+ data->path.path.track.tail->time
+ += (time.tm_gmtoff
+ - (offhours * 60 * 60
+ + offmins * 60));
+ }
+ }
+ }
+ }
+ /* Successfully parsed dateTime. */
+ data->state = INSIDE_PATH_POINT;
+ }
+
+ g_string_free(data->chars, TRUE);
+ data->chars = g_string_new("");
+ }
+ else
+ data->state = ERROR;
+ break;
+ case INSIDE_PATH_POINT_DESC:
+ /* only parse description for routes */
+ if(!strcmp((gchar*)name, "desc"))
{
- /* ...snr.. */
- tmp = g_strdup_printf("%02d", _gps_sat[i].snr);
- pango_layout_set_text(layout, tmp, 2);
- pango_layout_get_pixel_size(layout, &x1, &y1);
- gdk_draw_layout(widget->window,
- widget->style->fg_gc[GTK_STATE_NORMAL],
- xoffset + x + ((step - 2) - x1)/2,
- yoffset + y - 15,
- layout);
- g_free(tmp);
+ MACRO_ROUTE_INCREMENT_WTAIL(data->path.path.route);
+ data->path.path.route.wtail->point = data->path.path.route.tail;
+ data->path.path.route.wtail->desc
+ = g_string_free(data->chars, FALSE);
+ data->chars = g_string_new("");
+ data->state = INSIDE_PATH_POINT;
}
-
- /* ...and sat number */
- tmp = g_strdup_printf("%02d", _gps_sat[i].prn);
- pango_layout_set_text(layout, tmp, 2);
- pango_layout_get_pixel_size(layout, &x1, &y1);
- gdk_draw_layout(widget->window,
- widget->style->fg_gc[GTK_STATE_NORMAL],
- xoffset + x + ((step - 2) - x1)/2 ,
- yoffset + bymargin + 1,
- layout);
- g_free(tmp);
- }
- g_object_unref (gc1);
- g_object_unref (gc2);
+ else
+ data->state = ERROR;
+ break;
+ case UNKNOWN:
+ if(!--data->unknown_depth)
+ data->state = data->prev_state;
+ else
+ data->state = ERROR;
+ break;
+ default:
+ ;
}
- pango_font_description_free (fontdesc);
- g_object_unref (layout);
-
- return;
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
+/**
+ * Handle char data in the parsing of a GPX file.
+ */
static void
-draw_sat_details(GtkWidget *widget, guint x0, guint y0,
- guint width, guint height)
+gpx_chars(SaxData *data, const xmlChar *ch, int len)
{
- guint i, j, x, y, size, halfsize, xoffset, yoffset;
- guint x1, y1;
- gfloat tmp;
- GdkColor color;
- GdkGC *gc1, *gc2, *gc3, *gc;
- PangoContext *context = NULL;
- PangoLayout *layout = NULL;
- PangoFontDescription *fontdesc = NULL;
- gchar *buffer = NULL;
+ guint i;
+ vprintf("%s()\n", __PRETTY_FUNCTION__);
- size = MIN(width, height);
- halfsize = size/2;
- if(width > height)
- {
- xoffset = x0 + (width - height - 10) / 2;
- yoffset = y0 + 5;
- }
- else
+ switch(data->state)
{
- xoffset = x0 + 5;
- yoffset = y0 + (height - width - 10) / 2;
+ case ERROR:
+ case UNKNOWN:
+ break;
+ case INSIDE_PATH_POINT_TIME:
+ case INSIDE_PATH_POINT_DESC:
+ for(i = 0; i < len; i++)
+ data->chars = g_string_append_c(data->chars, ch[i]);
+ vprintf("%s\n", data->chars->str);
+ break;
+ default:
+ break;
}
- context = gtk_widget_get_pango_context(widget);
- layout = pango_layout_new(context);
- fontdesc = pango_font_description_new();
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
- pango_font_description_set_family(fontdesc,"Sans Serif");
- pango_font_description_set_size(fontdesc, 10*PANGO_SCALE);
- pango_layout_set_font_description (layout, fontdesc);
- pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
+/**
+ * Handle an entity in the parsing of a GPX file. We don't do anything
+ * special here.
+ */
+static xmlEntityPtr
+gpx_get_entity(SaxData *data, const xmlChar *name)
+{
+ vprintf("%s()\n", __PRETTY_FUNCTION__);
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+ return xmlGetPredefinedEntity(name);
+}
- /* 90 */
- gdk_draw_arc(widget->window,
- widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
- FALSE,
- xoffset + 2, yoffset + 2, size - 4, size - 4,
- 0, 64 * 360);
+/**
+ * Handle an error in the parsing of a GPX file.
+ */
+static void
+gpx_error(SaxData *data, const gchar *msg, ...)
+{
+ vprintf("%s()\n", __PRETTY_FUNCTION__);
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+ data->state = ERROR;
+}
- /* 60 */
- gdk_draw_arc(widget->window,
- widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
- FALSE,
- xoffset + size/6, yoffset + size/6,
- size/6*4, size/6*4,
- 0, 64 * 360);
+/**
+ * Parse the given character buffer of the given size, replacing the given
+ * Track's pointers with pointers to new arrays depending on the given
+ * policy, adding extra_bins slots in the arrays for new data.
+ *
+ * policy_old should be negative to indicate that the existing data should
+ * be prepended to the new GPX data, positive to indicate the opposite, and
+ * zero to indicate that we should throw away the old data.
+ *
+ * When importing tracks, we *prepend* the GPX data and provide extra_bins.
+ * When importing routes, we *append* in the case of regular routes, and we
+ * *replace* in the case of automatic routing. Routes get no extra bins.
+ */
+static gboolean
+parse_track_gpx(gchar *buffer, gint size, gint policy_old)
+{
+ SaxData data;
+ xmlSAXHandler sax_handler;
+ printf("%s()\n", __PRETTY_FUNCTION__);
- /* 30 */
- gdk_draw_arc(widget->window,
- widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
- FALSE,
- xoffset + size/6*2, yoffset + size/6*2,
- size/6*2, size/6*2,
- 0, 64 * 360);
+ data.path.path_type = TRACK;
+ MACRO_INIT_TRACK(data.path.path.track);
+ data.state = START;
+ data.chars = g_string_new("");
- guint line[12] = {0,30,60,90,120,150,180,210,240,270,300,330};
+ memset(&sax_handler, 0, sizeof(sax_handler));
+ sax_handler.characters = (charactersSAXFunc)gpx_chars;
+ sax_handler.startElement = (startElementSAXFunc)gpx_start_element;
+ sax_handler.endElement = (endElementSAXFunc)gpx_end_element;
+ sax_handler.entityDecl = (entityDeclSAXFunc)gpx_get_entity;
+ sax_handler.warning = (warningSAXFunc)gpx_error;
+ sax_handler.error = (errorSAXFunc)gpx_error;
+ sax_handler.fatalError = (fatalErrorSAXFunc)gpx_error;
- for(i = 0; i < 6; i++)
+ xmlSAXUserParseMemory(&sax_handler, &data, buffer, size);
+ g_string_free(data.chars, TRUE);
+
+ if(data.state != FINISH)
{
- /* line */
- tmp = (line[i] * (1.f / 180.f)) * PI;
- gdk_draw_line(widget->window,
- widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
- xoffset + halfsize + (halfsize -2) * sinf(tmp),
- yoffset + halfsize - (halfsize -2) * cosf(tmp),
- xoffset + halfsize - (halfsize -2) * sinf(tmp),
- yoffset + halfsize + (halfsize -2) * cosf(tmp));
+ vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+ return FALSE;
}
- for(i = 0; i < 12; i++)
+ /* Successful parsing - replace given Track structure. */
+ if(policy_old && _track.head)
{
- tmp = (line[i] * (1.f / 180.f)) * PI;
- /* azimuth */
- if(line[i] == 0)
- buffer = g_strdup_printf("N");
- else
- buffer = g_strdup_printf("%d\u00b0", line[i]);
- pango_layout_set_text(layout, buffer, strlen(buffer));
- pango_layout_get_pixel_size(layout, &x, &y);
- gdk_draw_layout(widget->window,
- widget->style->fg_gc[GTK_STATE_NORMAL],
- (xoffset + halfsize + (halfsize - size/12) * sinf(tmp)) - x/2,
- (yoffset + halfsize - (halfsize - size/12) * cosf(tmp)) - y/2,
- layout);
- g_free(buffer);
- }
+ TrackPoint *src_first;
+ Track *src, *dest;
- /* elevation 30 */
- tmp = (30 * (1.f / 180.f)) * PI;
- buffer = g_strdup_printf("30\u00b0");
- pango_layout_set_text(layout, buffer, strlen(buffer));
- pango_layout_get_pixel_size(layout, &x, &y);
- gdk_draw_layout(widget->window,
- widget->style->fg_gc[GTK_STATE_NORMAL],
- (xoffset + halfsize + size/6*2 * sinf(tmp)) - x/2,
- (yoffset + halfsize - size/6*2 * cosf(tmp)) - y/2,
- layout);
- g_free(buffer);
+ if(policy_old > 0)
+ {
+ /* Append to current track. */
+ src = &data.path.path.track;
+ dest = &_track;
+ }
+ else
+ {
+ /* Prepend to current track. */
+ src = &_track;
+ dest = &data.path.path.track;
+ }
- /* elevation 60 */
- tmp = (30 * (1.f / 180.f)) * PI;
- buffer = g_strdup_printf("60\u00b0");
- pango_layout_set_text(layout, buffer, strlen(buffer));
- pango_layout_get_pixel_size(layout, &x, &y);
- gdk_draw_layout(widget->window,
- widget->style->fg_gc[GTK_STATE_NORMAL],
- (xoffset + halfsize + size/6 * sinf(tmp)) - x/2,
- (yoffset + halfsize - size/6 * cosf(tmp)) - y/2,
- layout);
- g_free(buffer);
+ /* Find src_first non-zero point. */
+ for(src_first = src->head - 1; src_first++ != src->tail; )
+ if(src_first->point.unity)
+ break;
- color.red = 0;
- color.green = 0;
- color.blue = 0;
- gc1 = gdk_gc_new (widget->window);
- gdk_gc_set_rgb_fg_color (gc1, &color);
+ /* Append track points from src to dest. */
+ if(src->tail >= src_first)
+ {
+ guint num_dest_points = dest->tail - dest->head + 1;
+ guint num_src_points = src->tail - src_first + 1;
- color.red = 0;
- color.green = 0;
- color.blue = 0xffff;
- gc2 = gdk_gc_new (widget->window);
- gdk_gc_set_rgb_fg_color (gc2, &color);
+ /* Adjust dest->tail to be able to fit src track data
+ * plus room for more track data. */
+ track_resize(dest,
+ num_dest_points + num_src_points + ARRAY_CHUNK_SIZE);
- color.red = 0xffff;
- color.green = 0xffff;
- color.blue = 0xffff;
- gc3 = gdk_gc_new (widget->window);
- gdk_gc_set_rgb_fg_color (gc3, &color);
+ memcpy(dest->tail + 1, src_first,
+ num_src_points * sizeof(TrackPoint));
- for(i = 0; i < _gps.satinview; i++)
- {
- /* Sat used or not */
- gc = gc1;
- for(j = 0; j < _gps.satinuse ; j++)
- {
- if(_gps.satforfix[j] == _gps_sat[i].prn)
- {
- gc = gc2;
- break;
- }
+ dest->tail += num_src_points;
}
- tmp = (_gps_sat[i].azimuth * (1.f / 180.f)) * PI;
- x = xoffset + halfsize
- + (90 - _gps_sat[i].elevation)*halfsize/90 * sinf(tmp);
- y = yoffset + halfsize
- - (90 - _gps_sat[i].elevation)*halfsize/90 * cosf(tmp);
-
- gdk_draw_arc (widget->window,
- gc, TRUE,
- x - 10, y - 10, 20, 20,
- 0, 64 * 360);
-
- buffer = g_strdup_printf("%02d", _gps_sat[i].prn);
- pango_layout_set_text(layout, buffer, strlen(buffer));
- pango_layout_get_pixel_size(layout, &x1, &y1);
- gdk_draw_layout(widget->window,
- gc3,
- x - x1/2,
- y - y1/2,
- layout);
- g_free(buffer);
+ MACRO_CLEAR_TRACK(*src);
+ if(policy_old < 0)
+ _track = *dest;
+ }
+ else
+ {
+ MACRO_CLEAR_TRACK(_track);
+ /* Overwrite with data.track. */
+ _track = data.path.path.track;
+ track_resize(&_track,
+ _track.tail - _track.head + 1 + ARRAY_CHUNK_SIZE);
}
- g_object_unref (gc1);
- g_object_unref (gc2);
- g_object_unref (gc3);
-
- pango_font_description_free (fontdesc);
- g_object_unref (layout);
- return;
+ vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+ return TRUE;
}
-
static gboolean
-sat_details_panel_expose(GtkWidget *widget, GdkEventExpose *event)
+parse_route_gpx(gchar *buffer, gint size, gint policy_old)
{
- guint width, height, x, y;
- PangoContext *context = NULL;
- PangoLayout *layout = NULL;
- PangoFontDescription *fontdesc = NULL;
- gchar *buffer = NULL;
+ SaxData data;
+ xmlSAXHandler sax_handler;
+ printf("%s()\n", __PRETTY_FUNCTION__);
- width = widget->allocation.width;
- height = widget->allocation.height * 0.9;
+ data.path.path_type = ROUTE;
+ MACRO_INIT_ROUTE(data.path.path.route);
+ data.state = START;
+ data.chars = g_string_new("");
- draw_sat_info(widget, 0, 0, width/2, height, TRUE);
- draw_sat_details(widget, width/2, 0, width/2, height);
+ memset(&sax_handler, 0, sizeof(sax_handler));
+ sax_handler.characters = (charactersSAXFunc)gpx_chars;
+ sax_handler.startElement = (startElementSAXFunc)gpx_start_element;
+ sax_handler.endElement = (endElementSAXFunc)gpx_end_element;
+ sax_handler.entityDecl = (entityDeclSAXFunc)gpx_get_entity;
+ sax_handler.warning = (warningSAXFunc)gpx_error;
+ sax_handler.error = (errorSAXFunc)gpx_error;
+ sax_handler.fatalError = (fatalErrorSAXFunc)gpx_error;
- context = gtk_widget_get_pango_context(widget);
- layout = pango_layout_new(context);
- fontdesc = pango_font_description_new();
+ xmlSAXUserParseMemory(&sax_handler, &data, buffer, size);
+ g_string_free(data.chars, TRUE);
- pango_font_description_set_family(fontdesc,"Sans Serif");
- pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
- pango_font_description_set_size(fontdesc, 14*PANGO_SCALE);
- pango_layout_set_font_description (layout, fontdesc);
+ if(data.state != FINISH)
+ {
+ printf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+ return FALSE;
+ }
- buffer = g_strdup_printf(
- _("Satellites in view: %d; in use: %d"),
- _gps.satinview,
- _gps.satinuse);
- pango_layout_set_text(layout, buffer, strlen(buffer));
- pango_layout_get_pixel_size(layout, &x, &y);
- gdk_draw_layout(widget->window,
- widget->style->fg_gc[GTK_STATE_NORMAL],
- 10,
- height*0.9 + 10,
- layout);
- g_free(buffer);
-
- buffer = g_strdup_printf(_("HDOP: %.01f"), _gps.hdop);
- pango_layout_set_text(layout, buffer, strlen(buffer));
- pango_layout_get_pixel_size(layout, &x, &y);
- gdk_draw_layout(widget->window,
- widget->style->fg_gc[GTK_STATE_NORMAL],
- (width/8) - x/2,
- (height/6) - y/2,
- layout);
- g_free(buffer);
- buffer = g_strdup_printf(_("PDOP: %.01f"), _gps.pdop);
- pango_layout_set_text(layout, buffer, strlen(buffer));
- pango_layout_get_pixel_size(layout, &x, &y);
- gdk_draw_layout(widget->window,
- widget->style->fg_gc[GTK_STATE_NORMAL],
- (width/8) - x/2,
- (height/6) - y/2 + 20,
- layout);
- g_free(buffer);
- buffer = g_strdup_printf(_("VDOP: %.01f"), _gps.vdop);
- pango_layout_set_text(layout, buffer, strlen(buffer));
- pango_layout_get_pixel_size(layout, &x, &y);
- gdk_draw_layout(widget->window,
- widget->style->fg_gc[GTK_STATE_NORMAL],
- (width/8) - x/2,
- (height/6) - y/2 + 40,
- layout);
- g_free(buffer);
-
- pango_font_description_free (fontdesc);
- g_object_unref (layout);
-
- return TRUE;
-}
-
-static void
-gps_details(void)
-{
- GtkWidget *dialog;
- GtkWidget *table;
- GtkWidget *label;
- GtkWidget *notebook;
- printf("%s()\n", __PRETTY_FUNCTION__);
-
- dialog = gtk_dialog_new_with_buttons(_("GPS Details"),
- GTK_WINDOW(_window), GTK_DIALOG_MODAL,
- GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
- NULL);
-
- gtk_window_set_default_size(GTK_WINDOW(dialog), 600, 300);
+ if(policy_old && _route.head)
+ {
+ Point *src_first;
+ Route *src, *dest;
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
- notebook = gtk_notebook_new(), TRUE, TRUE, 0);
+ if(policy_old > 0)
+ {
+ /* Append to current route. */
+ src = &data.path.path.route;
+ dest = &_route;
+ }
+ else
+ {
+ /* Prepend to current route. */
+ src = &_route;
+ dest = &data.path.path.route;
+ }
- /* textual info */
- gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
- table = gtk_table_new(4, 6, FALSE),
- label = gtk_label_new(_("GPS Information")));
+ /* Find src_first non-zero point. */
+ for(src_first = src->head - 1; src_first++ != src->tail; )
+ if(src_first->unity)
+ break;
- _sat_details_panel = gtk_drawing_area_new ();
- gtk_widget_set_size_request (_sat_details_panel, 300, 300);
- /* sat details info */
- gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
- _sat_details_panel,
- label = gtk_label_new(_("Satellites details")));
- g_signal_connect (G_OBJECT (_sat_details_panel), "expose_event",
- G_CALLBACK (sat_details_panel_expose), NULL);
+ /* Append route points from src to dest. */
+ if(src->tail >= src_first)
+ {
+ WayPoint *curr;
+ guint num_dest_points = dest->tail - dest->head + 1;
+ guint num_src_points = src->tail - src_first + 1;
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(_("Latitude")),
- 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, 0, 20, 4);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
- gtk_table_attach(GTK_TABLE(table),
- _sdi_lat = gtk_label_new(" --- "),
- 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
- gtk_misc_set_alignment(GTK_MISC(_sdi_lat), 0.f, 0.5f);
+ /* Adjust dest->tail to be able to fit src route data
+ * plus room for more route data. */
+ route_resize(dest, num_dest_points + num_src_points);
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(_("Longitude")),
- 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, 0, 20, 4);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
- gtk_table_attach(GTK_TABLE(table),
- _sdi_lon = gtk_label_new(" --- "),
- 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
- gtk_misc_set_alignment(GTK_MISC(_sdi_lon), 0.f, 0.5f);
+ memcpy(dest->tail + 1, src_first,
+ num_src_points * sizeof(Point));
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(_("Speed")),
- 0, 1, 2, 3, GTK_EXPAND | GTK_FILL, 0, 20, 4);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
- gtk_table_attach(GTK_TABLE(table),
- _sdi_spd = gtk_label_new(" --- "),
- 1, 2, 2, 3, GTK_EXPAND | GTK_FILL, 0, 2, 4);
- gtk_misc_set_alignment(GTK_MISC(_sdi_spd), 0.f, 0.5f);
+ dest->tail += num_src_points;
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(_("Altitude")),
- 0, 1, 3, 4, GTK_EXPAND | GTK_FILL, 0, 20, 4);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
- gtk_table_attach(GTK_TABLE(table),
- _sdi_alt = gtk_label_new(" --- "),
- 1, 2, 3, 4, GTK_EXPAND | GTK_FILL, 0, 2, 4);
- gtk_misc_set_alignment(GTK_MISC(_sdi_alt), 0.f, 0.5f);
+ /* Append waypoints from src to dest->. */
+ route_wresize(dest, (dest->wtail - dest->whead)
+ + (src->wtail - src->whead) + 2);
+ for(curr = src->whead - 1; curr++ != src->wtail; )
+ {
+ (++(dest->wtail))->point = dest->head + num_dest_points
+ + (curr->point - src_first);
+ dest->wtail->desc = curr->desc;
+ }
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(_("Heading")),
- 0, 1, 4, 5, GTK_EXPAND | GTK_FILL, 0, 20, 4);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
- gtk_table_attach(GTK_TABLE(table),
- _sdi_hea = gtk_label_new(" --- "),
- 1, 2, 4, 5, GTK_EXPAND | GTK_FILL, 0, 2, 4);
- gtk_misc_set_alignment(GTK_MISC(_sdi_hea), 0.f, 0.5f);
+ }
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(_("Local time")),
- 0, 1, 5, 6, GTK_EXPAND | GTK_FILL, 0, 20, 4);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
- gtk_table_attach(GTK_TABLE(table),
- _sdi_tim = gtk_label_new(" --:--:-- "),
- 1, 2, 5, 6, GTK_EXPAND | GTK_FILL, 0, 2, 4);
- gtk_misc_set_alignment(GTK_MISC(_sdi_tim), 0.f, 0.5f);
+ /* Kill old route - don't use MACRO_CLEAR_ROUTE(), because that
+ * would free the string desc's that we just moved to data.route. */
+ g_free(src->head);
+ g_free(src->whead);
+ if(policy_old < 0)
+ _route = *dest;
+ }
+ else
+ {
+ MACRO_CLEAR_ROUTE(_route);
+ /* Overwrite with data.route. */
+ _route = data.path.path.route;
+ route_resize(&_route, _route.tail - _route.head + 1);
+ route_wresize(&_route, _route.wtail - _route.whead + 1);
+ }
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(_("Sat in view")),
- 2, 3, 0, 1, GTK_EXPAND | GTK_FILL, 0, 20, 4);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
- gtk_table_attach(GTK_TABLE(table),
- _sdi_vie = gtk_label_new("0"),
- 3, 4, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
- gtk_misc_set_alignment(GTK_MISC(_sdi_vie), 0.f, 0.5f);
+ vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+ return TRUE;
+}
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(_("Sat in use")),
- 2, 3, 1, 2, GTK_EXPAND | GTK_FILL, 0, 20, 4);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
- gtk_table_attach(GTK_TABLE(table),
- _sdi_use = gtk_label_new("0"),
- 3, 4, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
- gtk_misc_set_alignment(GTK_MISC(_sdi_use), 0.f, 0.5f);
+/****************************************************************************
+ * ABOVE: FILE-HANDLING ROUTINES *********************************************
+ ****************************************************************************/
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(_("Fix")),
- 2, 3, 2, 3, GTK_EXPAND | GTK_FILL, 0, 20, 4);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
- gtk_table_attach(GTK_TABLE(table),
- _sdi_fix = gtk_label_new(_("nofix")),
- 3, 4, 2, 3, GTK_EXPAND | GTK_FILL, 0, 2, 4);
- gtk_misc_set_alignment(GTK_MISC(_sdi_fix), 0.f, 0.5f);
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(_("Fix Quality")),
- 2, 3, 3, 4, GTK_EXPAND | GTK_FILL, 0, 20, 4);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
- gtk_table_attach(GTK_TABLE(table),
- _sdi_fqu = gtk_label_new(_("none")),
- 3, 4, 3, 4, GTK_EXPAND | GTK_FILL, 0, 2, 4);
- gtk_misc_set_alignment(GTK_MISC(_sdi_fix), 0.f, 0.5f);
+/****************************************************************************
+ * BELOW: ROUTINES **********************************************************
+ ****************************************************************************/
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(_("Max speed")),
- 2, 3, 5, 6, GTK_EXPAND | GTK_FILL, 0, 20, 4);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
- gtk_table_attach(GTK_TABLE(table),
- _sdi_msp = gtk_label_new(" --- "),
- 3, 4, 5, 6, GTK_EXPAND | GTK_FILL, 0, 2, 4);
- gtk_misc_set_alignment(GTK_MISC(_sdi_msp), 0.f, 0.5f);
+static gboolean
+gps_display_details(void)
+{
+ gchar *buffer, strtime[15];
+ printf("%s()\n", __PRETTY_FUNCTION__);
- gtk_widget_show_all(dialog);
- _satdetails_on = TRUE;
- gps_display_details();
- while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
+ if(_gps.fix < 2)
{
- _satdetails_on = FALSE;
- break;
+ /* no fix no fun */
+ gtk_label_set_label(GTK_LABEL(_sdi_lat), " --- ");
+ gtk_label_set_label(GTK_LABEL(_sdi_lon), " --- ");
+ gtk_label_set_label(GTK_LABEL(_sdi_spd), " --- ");
+ gtk_label_set_label(GTK_LABEL(_sdi_alt), " --- ");
+ gtk_label_set_label(GTK_LABEL(_sdi_hea), " --- ");
+ gtk_label_set_label(GTK_LABEL(_sdi_tim), " --:--:-- ");
}
- gtk_widget_destroy(dialog);
+ else
+ {
+ gfloat speed = _gps.speed * UNITS_CONVERT[_units];
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
+ /* latitude */
+ gtk_label_set_label(GTK_LABEL(_sdi_lat), _gps.slatitude);
-static gfloat
-calculate_distance(gfloat lat1, gfloat lon1, gfloat lat2, gfloat lon2)
-{
- gfloat dlat, dlon, slat, slon, a;
+ /* longitude */
+ gtk_label_set_label(GTK_LABEL(_sdi_lon), _gps.slongitude);
- /* Convert to radians. */
- lat1 *= (PI / 180.f);
- lon1 *= (PI / 180.f);
- lat2 *= (PI / 180.f);
- lon2 *= (PI / 180.f);
-
- dlat = lat2 - lat1;
- dlon = lon2 - lon1;
-
- slat = sinf(dlat / 2.f);
- slon = sinf(dlon / 2.f);
- a = (slat * slat) + (cosf(lat1) * cosf(lat2) * slon * slon);
-
- return ((2.f * atan2f(sqrtf(a), sqrtf(1.f - a))) * EARTH_RADIUS)
- * UNITS_CONVERT[_units];
-}
-
-/**
- * Pop up a modal dialog box with simple error information in it.
- */
-static void
-popup_error(GtkWidget *window, const gchar *error)
-{
- GtkWidget *dialog;
- printf("%s(\"%s\")\n", __PRETTY_FUNCTION__, error);
+ /* speed */
+ switch(_units)
+ {
+ case UNITS_MI:
+ buffer = g_strdup_printf("%.1f mph", speed);
+ break;
+ case UNITS_NM:
+ buffer = g_strdup_printf("%.1f kn", speed);
+ break;
+ default:
+ buffer = g_strdup_printf("%.1f km/h", speed);
+ break;
+ }
+ gtk_label_set_label(GTK_LABEL(_sdi_spd), buffer);
+ g_free(buffer);
- dialog = hildon_note_new_information(GTK_WINDOW(window), error);
+ /* altitude */
+ switch(_units)
+ {
+ case UNITS_MI:
+ case UNITS_NM:
+ buffer = g_strdup_printf("%d ft",
+ (guint)(_gps.altitude * 3.2808399f));
+ break;
+ default:
+ buffer = g_strdup_printf("%d m", _gps.altitude);
+ break;
+ }
+ gtk_label_set_label(GTK_LABEL(_sdi_alt), buffer);
+ g_free(buffer);
- gtk_dialog_run(GTK_DIALOG(dialog));
- gtk_widget_destroy(dialog);
+ /* heading */
+ buffer = g_strdup_printf("%0.0f\u00b0", _gps.heading);
+ gtk_label_set_label(GTK_LABEL(_sdi_hea), buffer);
+ g_free(buffer);
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
+ /* local time */
+ strftime(strtime, 15, "%X", &_gps.timeloc);
+ gtk_label_set_label(GTK_LABEL(_sdi_tim), strtime);
+ }
-static void
-db_connect()
-{
- gchar buffer[100];
- gchar *perror;
- gchar **pszResult;
- guint nRow, nColumn;
+ /* Sat in view */
+ buffer = g_strdup_printf("%d", _gps.satinview);
+ gtk_label_set_label(GTK_LABEL(_sdi_vie), buffer);
+ g_free(buffer);
- _dbconn = FALSE;
+ /* Sat in use */
+ buffer = g_strdup_printf("%d", _gps.satinuse);
+ gtk_label_set_label(GTK_LABEL(_sdi_use), buffer);
+ g_free(buffer);
- if(!_poi_db)
- return;
+ /* fix */
+ switch(_gps.fix)
+ {
+ case 2:
+ case 3: buffer = g_strdup_printf("%dD fix", _gps.fix); break;
+ default: buffer = g_strdup_printf("nofix"); break;
+ }
+ gtk_label_set_label(GTK_LABEL(_sdi_fix), buffer);
+ g_free(buffer);
- if(NULL == (_db = sqlite_open(_poi_db, 0666, &perror)))
+ if(_gps.fix == 1)
+ buffer = g_strdup("none");
+ else
{
- gchar buffer2[200];
- sprintf(buffer2, "%s: %s", _("Problem with POI database"), perror);
- popup_error(_window, buffer2);
- g_free(perror);
- return;
+ switch (_gps.fixquality)
+ {
+ case 1 : buffer = g_strdup_printf(_("SPS")); break;
+ case 2 : buffer = g_strdup_printf(_("DGPS")); break;
+ case 3 : buffer = g_strdup_printf(_("PPS")); break;
+ case 4 : buffer = g_strdup_printf(_("Real Time Kinematic")); break;
+ case 5 : buffer = g_strdup_printf(_("Float RTK")); break;
+ case 6 : buffer = g_strdup_printf(_("Estimated")); break;
+ case 7 : buffer = g_strdup_printf(_("Manual)")); break;
+ case 8 : buffer = g_strdup_printf(_("Simulation")); break;
+ default : buffer = g_strdup_printf(_("none")); break;
+ }
}
+ gtk_label_set_label(GTK_LABEL(_sdi_fqu), buffer);
+ g_free(buffer);
- if(SQLITE_OK != sqlite_get_table(_db, "select label from poi limit 1",
- &pszResult, &nRow, &nColumn, NULL))
+ /* max speed */
{
- if(SQLITE_OK != sqlite_exec(_db,
- /* Create the necessary tables... */
- "create table poi (poi_id integer PRIMARY KEY, lat real, "
- "lon real, label text, desc text, cat_id integer);"
- "create table category (cat_id integer PRIMARY KEY,"
- "label text, desc text, enabled integer);"
- /* Add some default categories... */
- "insert into category (label, desc, enabled) "
- "values ('Fuel',"
- "'Stations for purchasing fuel for vehicles.', 1);"
- "insert into category (label, desc, enabled) "
- "values ('Residence', "
- "'Houses, apartments, or other residences of import.', 1);"
- "insert into category (label, desc, enabled) "
- "values ('Dining', "
- "'Places to eat or drink.', 1);"
- "insert into category (label, desc, enabled) "
- "values ('Shopping/Services', "
- "'Places to shop or acquire services.', 1);"
- "insert into category (label, desc, enabled) "
- "values ('Recreation', "
- "'Indoor or Outdoor places to have fun.', 1);"
- "insert into category (label, desc, enabled) "
- "values ('Transportation', "
- "'Bus stops, airports, train stations, etc.', 1);"
- "insert into category (label, desc, enabled) "
- "values ('Lodging', "
- "'Places to stay temporarily or for the night.', 1);"
- "insert into category (label, desc, enabled) "
- "values ('School', "
- "'Elementary schools, college campuses, etc.', 1);"
- "insert into category (label, desc, enabled) "
- "values ('Business', "
- "'General places of business.', 1);"
- "insert into category (label, desc, enabled) "
- "values ('Landmark', "
- "'General landmarks.', 1);"
- "insert into category (label, desc, enabled) "
- "values ('Other', "
- "'Miscellaneous category for everything else.', 1);",
- NULL,
- NULL,
- &perror)
- && (SQLITE_OK != sqlite_get_table(_db,
- "select label from poi limit 1",
- &pszResult, &nRow, &nColumn, NULL)))
+ gfloat maxspeed = _gps.maxspeed * UNITS_CONVERT[_units];
+
+ /* speed */
+ switch(_units)
{
- sprintf(buffer, _("Failed to open or create database:\n%s"),
- _poi_db);
- popup_error(_window, buffer);
- sqlite_close(_db);
- return;
+ case UNITS_MI:
+ buffer = g_strdup_printf("%.1f mph", maxspeed);
+ break;
+ case UNITS_NM:
+ buffer = g_strdup_printf("%.1f kn", maxspeed);
+ break;
+ default:
+ buffer = g_strdup_printf("%.1f km/h", maxspeed);
+ break;
}
+ gtk_label_set_label(GTK_LABEL(_sdi_msp), buffer);
+ g_free(buffer);
}
- else
- sqlite_free_table(pszResult);
- _dbconn = TRUE;
+ /* refresh sat panel */
+ gtk_widget_queue_draw_area(GTK_WIDGET(_sat_details_panel),
+ 0, 0,
+ _sat_details_panel->allocation.width,
+ _sat_details_panel->allocation.height);
+
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+ return TRUE;
}
-/**
- * Set the connection state. This function controls all connection-related
- * banners.
- */
static void
-set_conn_state(ConnState new_conn_state)
+gps_display_data(void)
{
- printf("%s(%d)\n", __PRETTY_FUNCTION__, new_conn_state);
+ gchar *buffer, strtime[15];
+ printf("%s()\n", __PRETTY_FUNCTION__);
- switch(_conn_state = new_conn_state)
+ if(_gps.fix < 2)
{
- case RCVR_OFF:
- case RCVR_FIXED:
- if(_connect_banner)
- {
- gtk_widget_destroy(_connect_banner);
- _connect_banner = NULL;
- }
- if(_fix_banner)
- {
- gtk_widget_destroy(_fix_banner);
- _fix_banner = NULL;
- }
- break;
- case RCVR_DOWN:
- if(_fix_banner)
- {
- gtk_widget_destroy(_fix_banner);
- _fix_banner = NULL;
- }
- if(!_connect_banner)
- _connect_banner = hildon_banner_show_animation(
- _window, NULL, _("Searching for GPS receiver"));
- break;
- case RCVR_UP:
- if(_connect_banner)
- {
- gtk_widget_destroy(_connect_banner);
- _connect_banner = NULL;
- }
- if(!_fix_banner)
- _fix_banner = hildon_banner_show_progress(
- _window, NULL, _("Establishing GPS fix"));
- break;
- default: ; /* to quell warning. */
+ /* no fix no fun */
+ gtk_label_set_label(GTK_LABEL(_text_lat), " --- ");
+ gtk_label_set_label(GTK_LABEL(_text_lon), " --- ");
+ gtk_label_set_label(GTK_LABEL(_text_speed), " --- ");
+ gtk_label_set_label(GTK_LABEL(_text_alt), " --- ");
+ gtk_label_set_label(GTK_LABEL(_text_time), " --:--:-- ");
}
+ else
+ {
+ gfloat speed = _gps.speed * UNITS_CONVERT[_units];
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
+ /* latitude */
+ gtk_label_set_label(GTK_LABEL(_text_lat), _gps.slatitude);
-/**
- * Updates _near_point, _next_way, and _next_wpt. If quick is FALSE (as
- * it is when this function is called from route_find_nearest_point), then
- * the entire list (starting from _near_point) is searched. Otherwise, we
- * stop searching when we find a point that is farther away.
- */
-static gboolean
-route_update_nears(gboolean quick)
-{
- gboolean ret = FALSE;
- Point *curr, *near;
- WayPoint *wcurr, *wnext;
- guint near_dist_rough;
- printf("%s(%d)\n", __PRETTY_FUNCTION__, quick);
-
- /* If we have waypoints (_next_way != NULL), then determine the "next
- * waypoint", which is defined as the waypoint after the nearest point,
- * UNLESS we've passed that waypoint, in which case the waypoint after
- * that waypoint becomes the "next" waypoint. */
- if(_next_way)
- {
- /* First, set near_dist_rough with the new distance from _near_point. */
- near = _near_point;
- near_dist_rough = DISTANCE_ROUGH(_pos, *near);
+ /* longitude */
+ gtk_label_set_label(GTK_LABEL(_text_lon), _gps.slongitude);
- /* Now, search _route for a closer point. If quick is TRUE, then we'll
- * only search forward, only as long as we keep finding closer points.
- */
- for(curr = _near_point; curr++ != _route.tail; )
+ /* speed */
+ switch(_units)
{
- if(curr->unity)
- {
- guint dist_rough = DISTANCE_ROUGH(_pos, *curr);
- if(dist_rough <= near_dist_rough)
- {
- near = curr;
- near_dist_rough = dist_rough;
- }
- else if(quick)
- break;
- }
+ case UNITS_MI:
+ buffer = g_strdup_printf("Spd: %.1f mph", speed);
+ break;
+ case UNITS_NM:
+ buffer = g_strdup_printf("Spd: %.1f kn", speed);
+ break;
+ default:
+ buffer = g_strdup_printf("Spd: %.1f km/h", speed);
+ break;
}
+ gtk_label_set_label(GTK_LABEL(_text_speed), buffer);
+ g_free(buffer);
- /* Update _near_point. */
- _near_point = near;
- _near_point_dist_rough = near_dist_rough;
-
- for(wnext = wcurr = _next_way; wcurr != _route.wtail; wcurr++)
+ /* altitude */
+ switch(_units)
{
- if(wcurr->point < near
- /* Okay, this else if expression warrants explanation. If the
- * nearest track point happens to be a waypoint, then we want to
- * check if we have "passed" that waypoint. To check this, we
- * test the distance from _pos to the waypoint and from _pos to
- * _next_wpt, and if the former is increasing and the latter is
- * decreasing, then we have passed the waypoint, and thus we
- * should skip it. Note that if there is no _next_wpt, then
- * there is no next waypoint, so we do not skip it in that case. */
- || (wcurr->point == near && quick
- && (_next_wpt
- && (DISTANCE_ROUGH(_pos, *near) > _next_way_dist_rough
- && DISTANCE_ROUGH(_pos, *_next_wpt)
- < _next_wpt_dist_rough))))
- wnext = wcurr + 1;
- else
+ case UNITS_MI:
+ case UNITS_NM:
+ buffer = g_strdup_printf("Alt: %d ft",
+ (guint)(_gps.altitude * 3.2808399f));
break;
+ default:
+ buffer = g_strdup_printf("Alt: %d m", _gps.altitude);
}
+ gtk_label_set_label(GTK_LABEL(_text_alt), buffer);
+ g_free(buffer);
- if(wnext == _route.wtail && (wnext->point < near
- || (wnext->point == near && quick
- && (!_next_wpt
- || (DISTANCE_ROUGH(_pos, *near) > _next_way_dist_rough
- &&DISTANCE_ROUGH(_pos, *_next_wpt)
- < _next_wpt_dist_rough)))))
- {
- _next_way = NULL;
- _next_wpt = NULL;
- _next_way_dist_rough = -1;
- _next_wpt_dist_rough = -1;
- ret = TRUE;
- }
- /* Only update _next_way (and consequently _next_wpt) if _next_way is
- * different, and record that fact for return. */
- else
- {
- if(!quick || _next_way != wnext)
- {
- _next_way = wnext;
- _next_wpt = wnext->point;
- if(_next_wpt == _route.tail)
- _next_wpt = NULL;
- else
- {
- while(!(++_next_wpt)->unity)
- {
- if(_next_wpt == _route.tail)
- {
- _next_wpt = NULL;
- break;
- }
- }
- }
- ret = TRUE;
- }
- _next_way_dist_rough = DISTANCE_ROUGH(_pos, *wnext->point);
- if(_next_wpt)
- _next_wpt_dist_rough = DISTANCE_ROUGH(_pos, *_next_wpt);
- }
+ /* local time */
+ strftime(strtime, 15, "%X", &_gps.timeloc);
+ gtk_label_set_label(GTK_LABEL(_text_time), strtime);
}
- vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, ret);
- return ret;
+ /* refresh sat panel */
+ gtk_widget_queue_draw_area(GTK_WIDGET(_sat_panel),
+ 0, 0,
+ _sat_panel->allocation.width,
+ _sat_panel->allocation.height);
+
+ /* refresh heading panel*/
+ gtk_widget_queue_draw_area(GTK_WIDGET(_heading_panel),
+ 0, 0,
+ _heading_panel->allocation.width,
+ _heading_panel->allocation.height);
+
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+ return;
}
-/**
- * Reset the _near_point data by searching the entire route for the nearest
- * route point and waypoint.
- */
static void
-route_find_nearest_point()
+gps_hide_text(void)
{
printf("%s()\n", __PRETTY_FUNCTION__);
- /* Initialize _near_point. */
- _near_point = _route.head;
- while(!_near_point->unity && _near_point != _route.tail)
- _near_point++;
-
- /* Initialize _next_way. */
- if(_route.wtail == _route.whead - 1
- || (_autoroute_data.enabled && _route.wtail == _route.whead))
- _next_way = NULL;
- else
- /* We have at least one waypoint. */
- _next_way = (_autoroute_data.enabled ? _route.whead + 1 : _route.whead);
- _next_way_dist_rough = -1;
-
- /* Initialize _next_wpt. */
- _next_wpt = NULL;
- _next_wpt_dist_rough = -1;
+ /* Clear gps data */
+ _gps.fix = 1;
+ _gps.satinuse = 0;
+ _gps.satinview = 0;
- route_update_nears(FALSE);
+ if(_gps_info)
+ gps_display_data();
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
-/**
- * Render a single track line to _map_pixmap. If either point on the line
- * is a break (defined as unity == 0), a circle is drawn at the other point.
- * IT IS AN ERROR FOR BOTH POINTS TO INDICATE A BREAK.
- */
static void
-map_render_segment(GdkGC *gc_norm, GdkGC *gc_alt,
- guint unitx1, guint unity1, guint unitx2, guint unity2)
+gps_show_info(void)
{
- vprintf("%s()\n", __PRETTY_FUNCTION__);
+ printf("%s()\n", __PRETTY_FUNCTION__);
- if(!unity1)
- {
- guint x2, y2;
- x2 = unit2bufx(unitx2);
- y2 = unit2bufy(unity2);
- /* Make sure this circle will be visible. */
- if((x2 < BUF_WIDTH_PIXELS)
- && (y2 < BUF_HEIGHT_PIXELS))
- gdk_draw_arc(_map_pixmap, gc_alt,
- FALSE, /* FALSE: not filled. */
- x2 - _draw_line_width,
- y2 - _draw_line_width,
- 2 * _draw_line_width,
- 2 * _draw_line_width,
- 0, /* start at 0 degrees. */
- 360 * 64);
- }
- else if(!unity2)
- {
- guint x1, y1;
- x1 = unit2bufx(unitx1);
- y1 = unit2bufy(unity1);
- /* Make sure this circle will be visible. */
- if((x1 < BUF_WIDTH_PIXELS)
- && ((unsigned)y1 < BUF_HEIGHT_PIXELS))
- gdk_draw_arc(_map_pixmap, gc_alt,
- FALSE, /* FALSE: not filled. */
- x1 - _draw_line_width,
- y1 - _draw_line_width,
- 2 * _draw_line_width,
- 2 * _draw_line_width,
- 0, /* start at 0 degrees. */
- 360 * 64);
- }
+ if(_gps_info && _enable_gps)
+ gtk_widget_show_all(GTK_WIDGET(_gps_widget));
else
{
- gint x1, y1, x2, y2;
- x1 = unit2bufx(unitx1);
- y1 = unit2bufy(unity1);
- x2 = unit2bufx(unitx2);
- y2 = unit2bufy(unity2);
- /* Make sure this line could possibly be visible. */
- if(!((x1 > BUF_WIDTH_PIXELS && x2 > BUF_WIDTH_PIXELS)
- || (x1 < 0 && x2 < 0)
- || (y1 > BUF_HEIGHT_PIXELS && y2 > BUF_HEIGHT_PIXELS)
- || (y1 < 0 && y2 < 0)))
- gdk_draw_line(_map_pixmap, gc_norm, x1, y1, x2, y2);
+ gps_hide_text();
+ gtk_widget_hide_all(GTK_WIDGET(_gps_widget));
}
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
-/**
- * Render all track data onto the _map_pixmap. Note that this does not
- * clear the pixmap of previous track data (use map_force_redraw() for
- * that), and also note that this method does not queue any redraws, so it
- * is up to the caller to decide which part of the track really needs to be
- * redrawn.
- */
static void
-map_render_track()
+draw_sat_info(GtkWidget *widget, guint x0, guint y0,
+ guint width, guint height, gboolean showsnr)
{
- TrackPoint *curr;
- printf("%s()\n", __PRETTY_FUNCTION__);
-
- for(curr = _track.head; curr != _track.tail; curr++)
- map_render_segment(_gc_track, _gc_track_break,
- curr->point.unitx, curr->point.unity,
- curr[1].point.unitx, curr[1].point.unity);
+ PangoContext *context = NULL;
+ PangoLayout *layout = NULL;
+ PangoFontDescription *fontdesc = NULL;
+ GdkColor color;
+ GdkGC *gc1, *gc2, *gc;
+ guint step, i, j, snr_height, bymargin, xoffset, yoffset;
+ guint x, y, x1, y1;
+ gchar *tmp = NULL;
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
+ xoffset = x0;
+ yoffset = y0;
+ /* Bootom margin - 12% */
+ bymargin = height * 0.88f;
-/**
- * Render all track data onto the _map_pixmap. Note that this does not
- * clear the pixmap of previous track data (use map_force_redraw() for
- * that), and also note that this method does not queue any redraws, so it
- * is up to the caller to decide which part of the track really needs to be
- * redrawn.
- */
-static void
-map_render_route()
-{
- Point *curr;
- WayPoint *wcurr;
- printf("%s()\n", __PRETTY_FUNCTION__);
+ /* Bottom line */
+ gdk_draw_line(widget->window,
+ widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+ xoffset + 5, yoffset + bymargin,
+ xoffset + width - 10 - 2, yoffset + bymargin);
+ gdk_draw_line(widget->window,
+ widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+ xoffset + 5, yoffset + bymargin - 1,
+ xoffset + width - 10 - 2, yoffset + bymargin - 1);
- _visible_way_first = _visible_way_last = NULL;
- for(curr = _route.head, wcurr = _route.whead; curr != _route.tail; curr++)
+ context = gtk_widget_get_pango_context(widget);
+ layout = pango_layout_new(context);
+ fontdesc = pango_font_description_new();
+
+ pango_font_description_set_family(fontdesc,"Sans Serif");
+
+ if(_gps.satinview > 0 )
{
- if(wcurr <= _route.wtail && curr == wcurr->point)
+ pango_font_description_set_size(fontdesc, 8*PANGO_SCALE);
+
+ pango_layout_set_font_description (layout, fontdesc);
+ pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
+
+ /* Left margin - 5pix, Right margin - 5pix */
+ step = (width - 10) / _gps.satinview;
+
+ color.red = 0;
+ color.green = 0;
+ color.blue = 0;
+ gc1 = gdk_gc_new (widget->window);
+ gdk_gc_set_rgb_fg_color (gc1, &color);
+
+ color.red = 0;
+ color.green = 0;
+ color.blue = 0xffff;
+ gc2 = gdk_gc_new (widget->window);
+ gdk_gc_set_rgb_fg_color (gc2, &color);
+
+ for(i = 0; i < _gps.satinview; i++)
{
- guint x1 = unit2bufx(wcurr->point->unitx);
- guint y1 = unit2bufy(wcurr->point->unity);
- if((x1 < BUF_WIDTH_PIXELS)
- && (y1 < BUF_HEIGHT_PIXELS))
+ /* Sat used or not */
+ gc = gc1;
+ for(j = 0; j < _gps.satinuse ; j++)
{
- gdk_draw_arc(_map_pixmap,
- (wcurr==_next_way ? _gc_route_nextway : _gc_route_way),
- FALSE, /* FALSE: not filled. */
- x1 - _draw_line_width,
- y1 - _draw_line_width,
- 2 * _draw_line_width,
- 2 * _draw_line_width,
- 0, /* start at 0 degrees. */
- 360 * 64);
- if(!_visible_way_first)
- _visible_way_first = wcurr;
- _visible_way_last = wcurr;
+ if(_gps.satforfix[j] == _gps_sat[i].prn)
+ {
+ gc = gc2;
+ break;
+ }
}
- wcurr++;
- if(!curr[1].unity)
- continue;
- }
- map_render_segment(_gc_route, _gc_route_way,
- curr->unitx, curr->unity, curr[1].unitx, curr[1].unity);
- }
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
+ x = 5 + i * step;
+ snr_height = _gps_sat[i].snr * height * 0.78f / 100;
+ y = height * 0.1f + (height * 0.78f - snr_height);
-static void
-map_render_paths()
-{
- printf("%s()\n", __PRETTY_FUNCTION__);
+ /* draw sat rectangle... */
+ gdk_draw_rectangle(widget->window,
+ gc,
+ TRUE,
+ xoffset + x,
+ yoffset + y,
+ step - 2,
+ snr_height);
- if((_show_tracks & ROUTES_MASK) && _route.head)
- {
- map_render_route();
- if(_next_way == NULL)
- {
- guint x1 = unit2bufx(_route.tail[-1].unitx);
- guint y1 = unit2bufy(_route.tail[-1].unity);
- if((x1 < BUF_WIDTH_PIXELS)
- && (y1 < BUF_HEIGHT_PIXELS))
+ if(showsnr && _gps_sat[i].snr > 0)
{
- gdk_draw_arc(_map_pixmap,
- _gc_route_nextway,
- FALSE, /* FALSE: not filled. */
- x1 - _draw_line_width,
- y1 - _draw_line_width,
- 2 * _draw_line_width,
- 2 * _draw_line_width,
- 0, /* start at 0 degrees. */
- 360 * 64);
+ /* ...snr.. */
+ tmp = g_strdup_printf("%02d", _gps_sat[i].snr);
+ pango_layout_set_text(layout, tmp, 2);
+ pango_layout_get_pixel_size(layout, &x1, &y1);
+ gdk_draw_layout(widget->window,
+ widget->style->fg_gc[GTK_STATE_NORMAL],
+ xoffset + x + ((step - 2) - x1)/2,
+ yoffset + y - 15,
+ layout);
+ g_free(tmp);
}
+
+ /* ...and sat number */
+ tmp = g_strdup_printf("%02d", _gps_sat[i].prn);
+ pango_layout_set_text(layout, tmp, 2);
+ pango_layout_get_pixel_size(layout, &x1, &y1);
+ gdk_draw_layout(widget->window,
+ widget->style->fg_gc[GTK_STATE_NORMAL],
+ xoffset + x + ((step - 2) - x1)/2 ,
+ yoffset + bymargin + 1,
+ layout);
+ g_free(tmp);
}
+ g_object_unref (gc1);
+ g_object_unref (gc2);
}
- if(_show_tracks & TRACKS_MASK)
- map_render_track();
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+ pango_font_description_free (fontdesc);
+ g_object_unref (layout);
+
+ return;
}
static void
-track_resize(Track *track, guint size)
+draw_sat_details(GtkWidget *widget, guint x0, guint y0,
+ guint width, guint height)
{
- printf("%s()\n", __PRETTY_FUNCTION__);
+ guint i, j, x, y, size, halfsize, xoffset, yoffset;
+ guint x1, y1;
+ gfloat tmp;
+ GdkColor color;
+ GdkGC *gc1, *gc2, *gc3, *gc;
+ PangoContext *context = NULL;
+ PangoLayout *layout = NULL;
+ PangoFontDescription *fontdesc = NULL;
+ gchar *buffer = NULL;
- if(track->head + size != track->cap)
+ size = MIN(width, height);
+ halfsize = size/2;
+ if(width > height)
{
- TrackPoint *old_head = track->head;
- track->head = g_renew(TrackPoint, old_head, size);
- track->cap = track->head + size;
- if(track->head != old_head)
- track->tail = track->head + (track->tail - old_head);
+ xoffset = x0 + (width - height - 10) / 2;
+ yoffset = y0 + 5;
+ }
+ else
+ {
+ xoffset = x0 + 5;
+ yoffset = y0 + (height - width - 10) / 2;
}
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
+ context = gtk_widget_get_pango_context(widget);
+ layout = pango_layout_new(context);
+ fontdesc = pango_font_description_new();
-static void
-route_resize(Route *route, guint size)
-{
- printf("%s()\n", __PRETTY_FUNCTION__);
+ pango_font_description_set_family(fontdesc,"Sans Serif");
+ pango_font_description_set_size(fontdesc, 10*PANGO_SCALE);
+ pango_layout_set_font_description (layout, fontdesc);
+ pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
- if(route->head + size != route->cap)
- {
- Point *old_head = route->head;
- WayPoint *curr;
- route->head = g_renew(Point, old_head, size);
- route->cap = route->head + size;
- if(route->head != old_head)
- {
- route->tail = route->head + (route->tail - old_head);
+ /* 90 */
+ gdk_draw_arc(widget->window,
+ widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+ FALSE,
+ xoffset + 2, yoffset + 2, size - 4, size - 4,
+ 0, 64 * 360);
- /* Adjust all of the waypoints. */
- for(curr = route->whead - 1; curr++ != route->wtail; )
- curr->point = route->head + (curr->point - old_head);
- }
- }
+ /* 60 */
+ gdk_draw_arc(widget->window,
+ widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+ FALSE,
+ xoffset + size/6, yoffset + size/6,
+ size/6*4, size/6*4,
+ 0, 64 * 360);
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
+ /* 30 */
+ gdk_draw_arc(widget->window,
+ widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+ FALSE,
+ xoffset + size/6*2, yoffset + size/6*2,
+ size/6*2, size/6*2,
+ 0, 64 * 360);
-static void
-route_wresize(Route *route, guint wsize)
-{
- printf("%s()\n", __PRETTY_FUNCTION__);
+ guint line[12] = {0,30,60,90,120,150,180,210,240,270,300,330};
- if(route->whead + wsize != route->wcap)
+ for(i = 0; i < 6; i++)
{
- WayPoint *old_whead = route->whead;
- route->whead = g_renew(WayPoint, old_whead, wsize);
- route->wtail = route->whead + (route->wtail - old_whead);
- route->wcap = route->whead + wsize;
+ /* line */
+ tmp = (line[i] * (1.f / 180.f)) * PI;
+ gdk_draw_line(widget->window,
+ widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+ xoffset + halfsize + (halfsize -2) * sinf(tmp),
+ yoffset + halfsize - (halfsize -2) * cosf(tmp),
+ xoffset + halfsize - (halfsize -2) * sinf(tmp),
+ yoffset + halfsize + (halfsize -2) * cosf(tmp));
}
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-
-#define MACRO_TRACK_INCREMENT_TAIL(track) { \
- if(++(track).tail == (track).cap) \
- track_resize(&(track), (track).cap - (track).head + ARRAY_CHUNK_SIZE); \
-}
-
-#define MACRO_ROUTE_INCREMENT_TAIL(route) { \
- if(++(route).tail == (route).cap) \
- route_resize(&(route), (route).cap - (route).head + ARRAY_CHUNK_SIZE); \
-}
-
-#define MACRO_ROUTE_INCREMENT_WTAIL(route) { \
- if(++(route).wtail == (route).wcap) \
- route_wresize(&(route), \
- (route).wcap - (route).whead + ARRAY_CHUNK_SIZE); \
-}
+ for(i = 0; i < 12; i++)
+ {
+ tmp = (line[i] * (1.f / 180.f)) * PI;
+ /* azimuth */
+ if(line[i] == 0)
+ buffer = g_strdup_printf("N");
+ else
+ buffer = g_strdup_printf("%d\u00b0", line[i]);
+ pango_layout_set_text(layout, buffer, strlen(buffer));
+ pango_layout_get_pixel_size(layout, &x, &y);
+ gdk_draw_layout(widget->window,
+ widget->style->fg_gc[GTK_STATE_NORMAL],
+ (xoffset + halfsize + (halfsize - size/12) * sinf(tmp)) - x/2,
+ (yoffset + halfsize - (halfsize - size/12) * cosf(tmp)) - y/2,
+ layout);
+ g_free(buffer);
+ }
-/**
- * Add a point to the _track list. This function is slightly overloaded,
- * since it is what houses the check for "have we moved
- * significantly": it also initiates the re-calculation of the _near_point
- * data, as well as calling osso_display_state_on() when we have the focus.
- *
- * If a non-zero time is given, then the current position (as taken from the
- * _pos variable) is appended to _track with the given time. If time is zero,
- * then _pos_null is appended to _track with time zero (this produces a "break"
- * in the track).
- */
-static void
-track_add(time_t time, gboolean newly_fixed)
-{
- Point pos = (time == 0 ? _pos_null : _pos);
- printf("%s(%u, %u)\n", __PRETTY_FUNCTION__, pos.unitx, pos.unity);
+ /* elevation 30 */
+ tmp = (30 * (1.f / 180.f)) * PI;
+ buffer = g_strdup_printf("30\u00b0");
+ pango_layout_set_text(layout, buffer, strlen(buffer));
+ pango_layout_get_pixel_size(layout, &x, &y);
+ gdk_draw_layout(widget->window,
+ widget->style->fg_gc[GTK_STATE_NORMAL],
+ (xoffset + halfsize + size/6*2 * sinf(tmp)) - x/2,
+ (yoffset + halfsize - size/6*2 * cosf(tmp)) - y/2,
+ layout);
+ g_free(buffer);
- if(abs((gint)pos.unitx - _track.tail->point.unitx) > _draw_line_width
- || abs((gint)pos.unity - _track.tail->point.unity) > _draw_line_width)
- {
- if(time && _route.head
- && (newly_fixed ? (route_find_nearest_point(), TRUE)
- : route_update_nears(TRUE)))
- {
- map_render_paths();
- MACRO_QUEUE_DRAW_AREA();
- }
- if(_show_tracks & TRACKS_MASK)
- {
- /* Instead of calling map_render_paths(), we'll draw the new line
- * ourselves and call gtk_widget_queue_draw_area(). */
- gint tx1, ty1, tx2, ty2;
- map_render_segment(_gc_track, _gc_track_break,
- _track.tail->point.unitx, _track.tail->point.unity,
- pos.unitx, pos.unity);
- if(time && _track.tail->point.unity)
- {
- tx1 = unit2x(_track.tail->point.unitx);
- ty1 = unit2y(_track.tail->point.unity);
- tx2 = unit2x(pos.unitx);
- ty2 = unit2y(pos.unity);
- gtk_widget_queue_draw_area(_map_widget,
- MIN(tx1, tx2) - _draw_line_width,
- MIN(ty1, ty2) - _draw_line_width,
- abs(tx1 - tx2) + (2 * _draw_line_width),
- abs(ty1 - ty2) + (2 * _draw_line_width));
- }
- }
- MACRO_TRACK_INCREMENT_TAIL(_track);
+ /* elevation 60 */
+ tmp = (30 * (1.f / 180.f)) * PI;
+ buffer = g_strdup_printf("60\u00b0");
+ pango_layout_set_text(layout, buffer, strlen(buffer));
+ pango_layout_get_pixel_size(layout, &x, &y);
+ gdk_draw_layout(widget->window,
+ widget->style->fg_gc[GTK_STATE_NORMAL],
+ (xoffset + halfsize + size/6 * sinf(tmp)) - x/2,
+ (yoffset + halfsize - size/6 * cosf(tmp)) - y/2,
+ layout);
+ g_free(buffer);
- _track.tail->point = pos;
- _track.tail->time = time;
+ color.red = 0;
+ color.green = 0;
+ color.blue = 0;
+ gc1 = gdk_gc_new (widget->window);
+ gdk_gc_set_rgb_fg_color (gc1, &color);
- if(_autoroute_data.enabled && !_autoroute_data.in_progress
- && _near_point_dist_rough > 400)
- {
- _autoroute_data.in_progress = TRUE;
- g_idle_add((GSourceFunc)auto_route_dl_idle, NULL);
- }
+ color.red = 0;
+ color.green = 0;
+ color.blue = 0xffff;
+ gc2 = gdk_gc_new (widget->window);
+ gdk_gc_set_rgb_fg_color (gc2, &color);
- /* Keep the display on. */
- KEEP_DISPLAY_ON();
- }
+ color.red = 0xffff;
+ color.green = 0xffff;
+ color.blue = 0xffff;
+ gc3 = gdk_gc_new (widget->window);
+ gdk_gc_set_rgb_fg_color (gc3, &color);
- /* Check if we should announce upcoming waypoints. */
- if(time && _next_way_dist_rough
- < (20 + (guint)_speed) * _announce_notice_ratio * 3)
+ for(i = 0; i < _gps.satinview; i++)
{
- if(_enable_voice && strcmp(_next_way->desc, _last_spoken_phrase))
+ /* Sat used or not */
+ gc = gc1;
+ for(j = 0; j < _gps.satinuse ; j++)
{
- g_free(_last_spoken_phrase);
- _last_spoken_phrase = g_strdup(_next_way->desc);
- if(!fork())
+ if(_gps.satforfix[j] == _gps_sat[i].prn)
{
- /* We are the fork child. Synthesize the voice. */
- hildon_play_system_sound(
- "/usr/share/sounds/ui-information_note.wav");
- sleep(1);
-# define _voice_synth_path "/usr/bin/flite"
- printf("%s %s\n", _voice_synth_path, _last_spoken_phrase);
- execl(_voice_synth_path, _voice_synth_path,
- "-t", _last_spoken_phrase, (char *)NULL);
- exit(0);
+ gc = gc2;
+ break;
}
}
- hildon_banner_show_information(_window, NULL, _next_way->desc);
- }
-
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-/**
- * Disconnect from the receiver. This method cleans up any and everything
- * that might be associated with the receiver.
- */
-static void
-rcvr_disconnect()
-{
- printf("%s()\n", __PRETTY_FUNCTION__);
+ tmp = (_gps_sat[i].azimuth * (1.f / 180.f)) * PI;
+ x = xoffset + halfsize
+ + (90 - _gps_sat[i].elevation)*halfsize/90 * sinf(tmp);
+ y = yoffset + halfsize
+ - (90 - _gps_sat[i].elevation)*halfsize/90 * cosf(tmp);
- /* Remove watches. */
- if(_clater_sid)
- {
- g_source_remove(_clater_sid);
- _clater_sid = 0;
- }
- if(_error_sid)
- {
- g_source_remove(_error_sid);
- _error_sid = 0;
- }
- if(_connect_sid)
- {
- g_source_remove(_connect_sid);
- _connect_sid = 0;
- }
- if(_input_sid)
- {
- g_source_remove(_input_sid);
- _input_sid = 0;
- }
+ gdk_draw_arc (widget->window,
+ gc, TRUE,
+ x - 10, y - 10, 20, 20,
+ 0, 64 * 360);
- /* Destroy the GIOChannel object. */
- if(_channel)
- {
- g_io_channel_shutdown(_channel, FALSE, NULL);
- g_io_channel_unref(_channel);
- _channel = NULL;
+ buffer = g_strdup_printf("%02d", _gps_sat[i].prn);
+ pango_layout_set_text(layout, buffer, strlen(buffer));
+ pango_layout_get_pixel_size(layout, &x1, &y1);
+ gdk_draw_layout(widget->window,
+ gc3,
+ x - x1/2,
+ y - y1/2,
+ layout);
+ g_free(buffer);
}
+ g_object_unref (gc1);
+ g_object_unref (gc2);
+ g_object_unref (gc3);
- /* Close the file descriptor. */
- if(_fd != -1)
- {
- close(_fd);
- _fd = -1;
- }
+ pango_font_description_free (fontdesc);
+ g_object_unref (layout);
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+ return;
}
-static void rcvr_connect_later(); /* Forward declaration. */
-/**
- * Connect to the receiver.
- * This method assumes that _fd is -1 and _channel is NULL. If unsure, call
- * rcvr_disconnect() first.
- * Since this is an idle function, this function returns whether or not it
- * should be called again, which is always FALSE.
- */
static gboolean
-rcvr_connect_now()
+sat_details_panel_expose(GtkWidget *widget, GdkEventExpose *event)
{
- printf("%s(%d)\n", __PRETTY_FUNCTION__, _conn_state);
+ guint width, height, x, y;
+ PangoContext *context = NULL;
+ PangoLayout *layout = NULL;
+ PangoFontDescription *fontdesc = NULL;
+ gchar *buffer = NULL;
- if(_conn_state == RCVR_DOWN && _rcvr_mac) {
-#ifndef DEBUG
- /* Create the file descriptor. */
- if(*_rcvr_mac == '/')
- _fd = open(_rcvr_mac, O_RDONLY);
- else
- _fd = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
+ width = widget->allocation.width;
+ height = widget->allocation.height * 0.9;
- /* If file descriptor creation failed, try again later. Note that
- * there is no need to call rcvr_disconnect() because the file
- * descriptor creation is the first step, so if it fails, there's
- * nothing to clean up. */
- if(_fd == -1)
- rcvr_connect_later();
- else
- {
- /* Reset GPS read buffer */
- _gps_read_buf_curr = _gps_read_buf;
- *_gps_read_buf_curr = '\0';
+ draw_sat_info(widget, 0, 0, width/2, height, TRUE);
+ draw_sat_details(widget, width/2, 0, width/2, height);
- /* Create channel and add watches. */
- _channel = g_io_channel_unix_new(_fd);
- g_io_channel_set_flags(_channel, G_IO_FLAG_NONBLOCK, NULL);
- _error_sid = g_io_add_watch_full(_channel, G_PRIORITY_HIGH_IDLE,
- G_IO_ERR | G_IO_HUP, channel_cb_error, NULL, NULL);
- _connect_sid = g_io_add_watch_full(_channel, G_PRIORITY_HIGH_IDLE,
- G_IO_OUT, channel_cb_connect, NULL, NULL);
- if(*_rcvr_mac != '/'
- && connect(_fd, (struct sockaddr*)&_rcvr_addr,
- sizeof(_rcvr_addr))
- && errno != EAGAIN)
- {
- /* Connection failed. Disconnect and try again later. */
- rcvr_disconnect();
- rcvr_connect_later();
- }
- }
-#else
- /* We're in DEBUG mode, so instead of connecting, skip to FIXED. */
- set_conn_state(RCVR_FIXED);
-#endif
- }
+ context = gtk_widget_get_pango_context(widget);
+ layout = pango_layout_new(context);
+ fontdesc = pango_font_description_new();
- _clater_sid = 0;
+ pango_font_description_set_family(fontdesc,"Sans Serif");
+ pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
+ pango_font_description_set_size(fontdesc, 14*PANGO_SCALE);
+ pango_layout_set_font_description (layout, fontdesc);
- vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
- return FALSE;
-}
+ buffer = g_strdup_printf(
+ _("Satellites in view: %d; in use: %d"),
+ _gps.satinview,
+ _gps.satinuse);
+ pango_layout_set_text(layout, buffer, strlen(buffer));
+ pango_layout_get_pixel_size(layout, &x, &y);
+ gdk_draw_layout(widget->window,
+ widget->style->fg_gc[GTK_STATE_NORMAL],
+ 10,
+ height*0.9 + 10,
+ layout);
+ g_free(buffer);
-/**
- * Place a request to connect about 1 second after the function is called.
- */
-static void
-rcvr_connect_later()
-{
- printf("%s()\n", __PRETTY_FUNCTION__);
+ buffer = g_strdup_printf(_("HDOP: %.01f"), _gps.hdop);
+ pango_layout_set_text(layout, buffer, strlen(buffer));
+ pango_layout_get_pixel_size(layout, &x, &y);
+ gdk_draw_layout(widget->window,
+ widget->style->fg_gc[GTK_STATE_NORMAL],
+ (width/8) - x/2,
+ (height/6) - y/2,
+ layout);
+ g_free(buffer);
+ buffer = g_strdup_printf(_("PDOP: %.01f"), _gps.pdop);
+ pango_layout_set_text(layout, buffer, strlen(buffer));
+ pango_layout_get_pixel_size(layout, &x, &y);
+ gdk_draw_layout(widget->window,
+ widget->style->fg_gc[GTK_STATE_NORMAL],
+ (width/8) - x/2,
+ (height/6) - y/2 + 20,
+ layout);
+ g_free(buffer);
+ buffer = g_strdup_printf(_("VDOP: %.01f"), _gps.vdop);
+ pango_layout_set_text(layout, buffer, strlen(buffer));
+ pango_layout_get_pixel_size(layout, &x, &y);
+ gdk_draw_layout(widget->window,
+ widget->style->fg_gc[GTK_STATE_NORMAL],
+ (width/8) - x/2,
+ (height/6) - y/2 + 40,
+ layout);
+ g_free(buffer);
- _clater_sid = g_timeout_add(1000, (GSourceFunc)rcvr_connect_now, NULL);
+ pango_font_description_free (fontdesc);
+ g_object_unref (layout);
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+ return TRUE;
}
-/**
- * Convert the float lat/lon/speed/heading data into integer units.
- */
static void
-integerize_data()
+gps_details(void)
{
- gfloat tmp;
+ GtkWidget *dialog;
+ GtkWidget *table;
+ GtkWidget *label;
+ GtkWidget *notebook;
printf("%s()\n", __PRETTY_FUNCTION__);
- latlon2unit(_pos_lat, _pos_lon, _pos.unitx, _pos.unity);
-
- tmp = (_heading * (1.f / 180.f)) * PI;
- _vel_offsetx = (gint)(floorf(_speed * sinf(tmp) + 0.5f));
- _vel_offsety = -(gint)(floorf(_speed * cosf(tmp) + 0.5f));
+ dialog = gtk_dialog_new_with_buttons(_("GPS Details"),
+ GTK_WINDOW(_window), GTK_DIALOG_MODAL,
+ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+ NULL);
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
+ gtk_window_set_default_size(GTK_WINDOW(dialog), 600, 300);
-/**
- * Update all GdkGC objects to reflect the current _draw_line_width.
- */
-#define UPDATE_GC(gc) \
- gdk_gc_set_line_attributes(gc, \
- _draw_line_width, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
-static void
-update_gcs()
-{
- printf("%s()\n", __PRETTY_FUNCTION__);
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+ notebook = gtk_notebook_new(), TRUE, TRUE, 0);
- gdk_color_alloc(gtk_widget_get_colormap(_map_widget),
- &_color_mark);
- gdk_color_alloc(gtk_widget_get_colormap(_map_widget),
- &_color_mark_velocity);
- gdk_color_alloc(gtk_widget_get_colormap(_map_widget),
- &_color_mark_old);
- gdk_color_alloc(gtk_widget_get_colormap(_map_widget),
- &_color_track);
- gdk_color_alloc(gtk_widget_get_colormap(_map_widget),
- &_color_track_break);
- gdk_color_alloc(gtk_widget_get_colormap(_map_widget),
- &_color_route);
- gdk_color_alloc(gtk_widget_get_colormap(_map_widget),
- &_color_route_way);
- gdk_color_alloc(gtk_widget_get_colormap(_map_widget),
- &_color_route_nextway);
- gdk_color_alloc(gtk_widget_get_colormap(_map_widget),
- &_color_poi);
+ /* textual info */
+ gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
+ table = gtk_table_new(4, 6, FALSE),
+ label = gtk_label_new(_("GPS Information")));
- if(_gc_mark)
- {
- g_object_unref(_gc_mark);
- g_object_unref(_gc_mark_velocity);
- g_object_unref(_gc_mark_old);
- g_object_unref(_gc_track);
- g_object_unref(_gc_track_break);
- g_object_unref(_gc_route);
- g_object_unref(_gc_route_way);
- g_object_unref(_gc_route_nextway);
- g_object_unref(_gc_poi);
- }
+ _sat_details_panel = gtk_drawing_area_new ();
+ gtk_widget_set_size_request (_sat_details_panel, 300, 300);
+ /* sat details info */
+ gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
+ _sat_details_panel,
+ label = gtk_label_new(_("Satellites details")));
+ g_signal_connect (G_OBJECT (_sat_details_panel), "expose_event",
+ G_CALLBACK (sat_details_panel_expose), NULL);
- /* _gc_mark is used to draw the mark when data is current. */
- _gc_mark = gdk_gc_new(_map_pixmap);
- gdk_gc_set_foreground(_gc_mark, &_color_mark);
- gdk_gc_set_line_attributes(_gc_mark,
- _draw_line_width, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_label_new(_("Latitude")),
+ 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, 0, 20, 4);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table),
+ _sdi_lat = gtk_label_new(" --- "),
+ 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+ gtk_misc_set_alignment(GTK_MISC(_sdi_lat), 0.f, 0.5f);
- /* _gc_mark_old is used to draw the mark when data is old. */
- _gc_mark_old = gdk_gc_new(_map_pixmap);
- gdk_gc_set_foreground(_gc_mark_old, &_color_mark_old);
- gdk_gc_set_line_attributes(_gc_mark_old,
- _draw_line_width, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_label_new(_("Longitude")),
+ 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, 0, 20, 4);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table),
+ _sdi_lon = gtk_label_new(" --- "),
+ 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+ gtk_misc_set_alignment(GTK_MISC(_sdi_lon), 0.f, 0.5f);
- /* _gc_mark_velocity is used to draw the vel_current line. */
- _gc_mark_velocity = gdk_gc_new(_map_pixmap);
- gdk_gc_set_foreground(_gc_mark_velocity, &_color_mark_velocity);
- gdk_gc_set_line_attributes(_gc_mark_velocity,
- _draw_line_width, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_label_new(_("Speed")),
+ 0, 1, 2, 3, GTK_EXPAND | GTK_FILL, 0, 20, 4);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table),
+ _sdi_spd = gtk_label_new(" --- "),
+ 1, 2, 2, 3, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+ gtk_misc_set_alignment(GTK_MISC(_sdi_spd), 0.f, 0.5f);
- /* _gc_track is used to draw the track line. */
- _gc_track = gdk_gc_new(_map_pixmap);
- gdk_gc_set_foreground(_gc_track, &_color_track);
- gdk_gc_set_line_attributes(_gc_track,
- _draw_line_width, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_label_new(_("Altitude")),
+ 0, 1, 3, 4, GTK_EXPAND | GTK_FILL, 0, 20, 4);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table),
+ _sdi_alt = gtk_label_new(" --- "),
+ 1, 2, 3, 4, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+ gtk_misc_set_alignment(GTK_MISC(_sdi_alt), 0.f, 0.5f);
- /* _gc_track_break is used to draw the track_break dots. */
- _gc_track_break = gdk_gc_new(_map_pixmap);
- gdk_gc_set_foreground(_gc_track_break, &_color_track_break);
- gdk_gc_set_line_attributes(_gc_track_break,
- _draw_line_width, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_label_new(_("Heading")),
+ 0, 1, 4, 5, GTK_EXPAND | GTK_FILL, 0, 20, 4);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table),
+ _sdi_hea = gtk_label_new(" --- "),
+ 1, 2, 4, 5, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+ gtk_misc_set_alignment(GTK_MISC(_sdi_hea), 0.f, 0.5f);
- /* _gc_route is used to draw the route line. */
- _gc_route = gdk_gc_new(_map_pixmap);
- gdk_gc_set_foreground(_gc_route, &_color_route);
- gdk_gc_set_line_attributes(_gc_route,
- _draw_line_width, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_label_new(_("Local time")),
+ 0, 1, 5, 6, GTK_EXPAND | GTK_FILL, 0, 20, 4);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table),
+ _sdi_tim = gtk_label_new(" --:--:-- "),
+ 1, 2, 5, 6, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+ gtk_misc_set_alignment(GTK_MISC(_sdi_tim), 0.f, 0.5f);
- /* _way_gc is used to draw the waypoint dots. */
- _gc_route_way = gdk_gc_new(_map_pixmap);
- gdk_gc_set_foreground(_gc_route_way, &_color_route_way);
- gdk_gc_set_line_attributes(_gc_route_way,
- _draw_line_width, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_label_new(_("Sat in view")),
+ 2, 3, 0, 1, GTK_EXPAND | GTK_FILL, 0, 20, 4);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table),
+ _sdi_vie = gtk_label_new("0"),
+ 3, 4, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+ gtk_misc_set_alignment(GTK_MISC(_sdi_vie), 0.f, 0.5f);
- /* _gc_route_nextway is used to draw the next_way labels. */
- _gc_route_nextway = gdk_gc_new(_map_pixmap);
- gdk_gc_set_foreground(_gc_route_nextway, &_color_route_nextway);
- gdk_gc_set_line_attributes(_gc_route_nextway,
- _draw_line_width, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_label_new(_("Sat in use")),
+ 2, 3, 1, 2, GTK_EXPAND | GTK_FILL, 0, 20, 4);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table),
+ _sdi_use = gtk_label_new("0"),
+ 3, 4, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+ gtk_misc_set_alignment(GTK_MISC(_sdi_use), 0.f, 0.5f);
- /* _gc_poi is used to draw the default POI icon. */
- _gc_poi = gdk_gc_new(_map_pixmap);
- gdk_gc_set_foreground(_gc_poi, &_color_poi);
- gdk_gc_set_background(_gc_poi, &_color_poi);
- gdk_gc_set_line_attributes(_gc_poi,
- _draw_line_width, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_label_new(_("Fix")),
+ 2, 3, 2, 3, GTK_EXPAND | GTK_FILL, 0, 20, 4);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table),
+ _sdi_fix = gtk_label_new(_("nofix")),
+ 3, 4, 2, 3, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+ gtk_misc_set_alignment(GTK_MISC(_sdi_fix), 0.f, 0.5f);
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_label_new(_("Fix Quality")),
+ 2, 3, 3, 4, GTK_EXPAND | GTK_FILL, 0, 20, 4);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table),
+ _sdi_fqu = gtk_label_new(_("none")),
+ 3, 4, 3, 4, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+ gtk_misc_set_alignment(GTK_MISC(_sdi_fix), 0.f, 0.5f);
-/**
- * Save all configuration data to GCONF.
- */
-static void
-config_save()
-{
- GConfClient *gconf_client = gconf_client_get_default();
- gchar buffer[16];
- printf("%s()\n", __PRETTY_FUNCTION__);
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_label_new(_("Max speed")),
+ 2, 3, 5, 6, GTK_EXPAND | GTK_FILL, 0, 20, 4);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table),
+ _sdi_msp = gtk_label_new(" --- "),
+ 3, 4, 5, 6, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+ gtk_misc_set_alignment(GTK_MISC(_sdi_msp), 0.f, 0.5f);
- if(!gconf_client)
+ gtk_widget_show_all(dialog);
+ _satdetails_on = TRUE;
+ gps_display_details();
+ while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
{
- popup_error(_window,
- _("Failed to initialize GConf. Settings were not saved."));
- return;
+ _satdetails_on = FALSE;
+ break;
}
+ gtk_widget_destroy(dialog);
- /* Save Receiver MAC from GConf. */
- if(_rcvr_mac)
- gconf_client_set_string(gconf_client,
- GCONF_KEY_RCVR_MAC, _rcvr_mac, NULL);
- else
- gconf_client_unset(gconf_client,
- GCONF_KEY_RCVR_MAC, NULL);
-
- /* Save Receiver Channel to GConf. */
- gconf_client_set_int(gconf_client,
- GCONF_KEY_RCVR_CHAN, _rcvr_addr.rc_channel, NULL);
-
- /* Save Map Download URI Format. */
- gconf_client_set_string(gconf_client,
- GCONF_KEY_MAP_URI_FORMAT, _curr_repo->url, NULL);
-
- /* Save Map Download Zoom Steps. */
- gconf_client_set_int(gconf_client,
- GCONF_KEY_MAP_ZOOM_STEPS, _curr_repo->dl_zoom_steps, NULL);
-
- /* Save Map Cache Directory. */
- if(_curr_repo->cache_dir)
- gconf_client_set_string(gconf_client,
- GCONF_KEY_MAP_DIR_NAME, _curr_repo->cache_dir, NULL);
-
- /* Save Auto-Download. */
- gconf_client_set_bool(gconf_client,
- GCONF_KEY_AUTO_DOWNLOAD, _auto_download, NULL);
-
- /* Save Auto-Center Sensitivity. */
- gconf_client_set_int(gconf_client,
- GCONF_KEY_CENTER_SENSITIVITY, _center_ratio, NULL);
-
- /* Save Auto-Center Lead Amount. */
- gconf_client_set_int(gconf_client,
- GCONF_KEY_LEAD_AMOUNT, _lead_ratio, NULL);
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
- /* Save Draw Line Width. */
- gconf_client_set_int(gconf_client,
- GCONF_KEY_DRAW_LINE_WIDTH, _draw_line_width, NULL);
+static gfloat
+calculate_distance(gfloat lat1, gfloat lon1, gfloat lat2, gfloat lon2)
+{
+ gfloat dlat, dlon, slat, slon, a;
- /* Save Announce Advance Notice Ratio. */
- gconf_client_set_int(gconf_client,
- GCONF_KEY_ANNOUNCE_NOTICE, _announce_notice_ratio, NULL);
+ /* Convert to radians. */
+ lat1 *= (PI / 180.f);
+ lon1 *= (PI / 180.f);
+ lat2 *= (PI / 180.f);
+ lon2 *= (PI / 180.f);
- /* Save Enable Voice flag. */
- gconf_client_set_bool(gconf_client,
- GCONF_KEY_ENABLE_VOICE, _enable_voice, NULL);
+ dlat = lat2 - lat1;
+ dlon = lon2 - lon1;
- /* Save Keep On When Fullscreen flag. */
- gconf_client_set_bool(gconf_client,
- GCONF_KEY_ALWAYS_KEEP_ON, _always_keep_on, NULL);
+ slat = sinf(dlat / 2.f);
+ slon = sinf(dlon / 2.f);
+ a = (slat * slat) + (cosf(lat1) * cosf(lat2) * slon * slon);
- /* Save Units. */
- gconf_client_set_string(gconf_client,
- GCONF_KEY_UNITS, UNITS_TEXT[_units], NULL);
+ return ((2.f * atan2f(sqrtf(a), sqrtf(1.f - a))) * EARTH_RADIUS)
+ * UNITS_CONVERT[_units];
+}
- /* Save Escape Key Function. */
- gconf_client_set_string(gconf_client,
- GCONF_KEY_ESCAPE_KEY, ESCAPE_KEY_TEXT[_escape_key], NULL);
+static void
+db_connect()
+{
+ gchar buffer[100];
+ gchar *perror;
+ gchar **pszResult;
+ guint nRow, nColumn;
- /* Save last saved latitude. */
- gconf_client_set_float(gconf_client,
- GCONF_KEY_LAT, _pos_lat, NULL);
+ _dbconn = FALSE;
- /* Save last saved longitude. */
- gconf_client_set_float(gconf_client,
- GCONF_KEY_LON, _pos_lon, NULL);
+ if(!_poi_db)
+ return;
- /* Save last center point. */
+ if(NULL == (_db = sqlite_open(_poi_db, 0666, &perror)))
{
- gfloat center_lat, center_lon;
- unit2latlon(_center.unitx, _center.unity, center_lat, center_lon);
-
- /* Save last center latitude. */
- gconf_client_set_float(gconf_client,
- GCONF_KEY_CENTER_LAT, center_lat, NULL);
+ gchar buffer2[200];
+ sprintf(buffer2, "%s: %s", _("Problem with POI database"), perror);
+ popup_error(_window, buffer2);
+ g_free(perror);
+ return;
+ }
- /* Save last center longitude. */
- gconf_client_set_float(gconf_client,
- GCONF_KEY_CENTER_LON, center_lon, NULL);
+ if(SQLITE_OK != sqlite_get_table(_db, "select label from poi limit 1",
+ &pszResult, &nRow, &nColumn, NULL))
+ {
+ if(SQLITE_OK != sqlite_exec(_db,
+ /* Create the necessary tables... */
+ "create table poi (poi_id integer PRIMARY KEY, lat real, "
+ "lon real, label text, desc text, cat_id integer);"
+ "create table category (cat_id integer PRIMARY KEY,"
+ "label text, desc text, enabled integer);"
+ /* Add some default categories... */
+ "insert into category (label, desc, enabled) "
+ "values ('Fuel',"
+ "'Stations for purchasing fuel for vehicles.', 1);"
+ "insert into category (label, desc, enabled) "
+ "values ('Residence', "
+ "'Houses, apartments, or other residences of import.', 1);"
+ "insert into category (label, desc, enabled) "
+ "values ('Dining', "
+ "'Places to eat or drink.', 1);"
+ "insert into category (label, desc, enabled) "
+ "values ('Shopping/Services', "
+ "'Places to shop or acquire services.', 1);"
+ "insert into category (label, desc, enabled) "
+ "values ('Recreation', "
+ "'Indoor or Outdoor places to have fun.', 1);"
+ "insert into category (label, desc, enabled) "
+ "values ('Transportation', "
+ "'Bus stops, airports, train stations, etc.', 1);"
+ "insert into category (label, desc, enabled) "
+ "values ('Lodging', "
+ "'Places to stay temporarily or for the night.', 1);"
+ "insert into category (label, desc, enabled) "
+ "values ('School', "
+ "'Elementary schools, college campuses, etc.', 1);"
+ "insert into category (label, desc, enabled) "
+ "values ('Business', "
+ "'General places of business.', 1);"
+ "insert into category (label, desc, enabled) "
+ "values ('Landmark', "
+ "'General landmarks.', 1);"
+ "insert into category (label, desc, enabled) "
+ "values ('Other', "
+ "'Miscellaneous category for everything else.', 1);",
+ NULL,
+ NULL,
+ &perror)
+ && (SQLITE_OK != sqlite_get_table(_db,
+ "select label from poi limit 1",
+ &pszResult, &nRow, &nColumn, NULL)))
+ {
+ sprintf(buffer, _("Failed to open or create database:\n%s"),
+ _poi_db);
+ popup_error(_window, buffer);
+ sqlite_close(_db);
+ return;
+ }
}
+ else
+ sqlite_free_table(pszResult);
- /* Save last Zoom Level. */
- gconf_client_set_int(gconf_client,
- GCONF_KEY_ZOOM, _zoom, NULL);
+ _dbconn = TRUE;
+}
- /* Save Route Directory. */
- if(_route_dir_uri)
- gconf_client_set_string(gconf_client,
- GCONF_KEY_ROUTEDIR, _route_dir_uri, NULL);
+/**
+ * Set the connection state. This function controls all connection-related
+ * banners.
+ */
+static void
+set_conn_state(ConnState new_conn_state)
+{
+ printf("%s(%d)\n", __PRETTY_FUNCTION__, new_conn_state);
- /* Save the repositories. */
+ switch(_conn_state = new_conn_state)
{
- GList *curr = _repo_list;
- GSList *temp_list = NULL;
- gint curr_repo_index = 0;
-
- for(curr = _repo_list; curr != NULL; curr = curr->next)
- {
- /* Build from each part of a repo, delimited by newline characters:
- * 1. url
- * 2. cache_dir
- * 3. dl_zoom_steps
- * 4. view_zoom_steps
- */
- RepoData *rd = curr->data;
- gchar buffer[1024];
- sprintf(buffer, "%s\n%s\n%s\n%d\n%d\n",
- rd->name,
- rd->url,
- rd->cache_dir,
- rd->dl_zoom_steps,
- rd->view_zoom_steps);
- temp_list = g_slist_append(temp_list, g_strdup(buffer));
- if(rd == _curr_repo)
- gconf_client_set_int(gconf_client,
- GCONF_KEY_CURRREPO, curr_repo_index, NULL);
- curr_repo_index++;
- }
- gconf_client_set_list(gconf_client,
- GCONF_KEY_REPOSITORIES, GCONF_VALUE_STRING, temp_list, NULL);
+ case RCVR_OFF:
+ case RCVR_FIXED:
+ if(_connect_banner)
+ {
+ gtk_widget_destroy(_connect_banner);
+ _connect_banner = NULL;
+ }
+ if(_fix_banner)
+ {
+ gtk_widget_destroy(_fix_banner);
+ _fix_banner = NULL;
+ }
+ break;
+ case RCVR_DOWN:
+ if(_fix_banner)
+ {
+ gtk_widget_destroy(_fix_banner);
+ _fix_banner = NULL;
+ }
+ if(!_connect_banner)
+ _connect_banner = hildon_banner_show_animation(
+ _window, NULL, _("Searching for GPS receiver"));
+ break;
+ case RCVR_UP:
+ if(_connect_banner)
+ {
+ gtk_widget_destroy(_connect_banner);
+ _connect_banner = NULL;
+ }
+ if(!_fix_banner)
+ _fix_banner = hildon_banner_show_progress(
+ _window, NULL, _("Establishing GPS fix"));
+ break;
+ default: ; /* to quell warning. */
}
- /* Save Last Track File. */
- if(_track_file_uri)
- gconf_client_set_string(gconf_client,
- GCONF_KEY_TRACKFILE, _track_file_uri, NULL);
-
- /* Save Auto-Center Mode. */
- gconf_client_set_int(gconf_client,
- GCONF_KEY_AUTOCENTER_MODE, _center_mode, NULL);
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
- /* Save Show Tracks flag. */
- gconf_client_set_bool(gconf_client,
- GCONF_KEY_SHOWTRACKS, _show_tracks & TRACKS_MASK, NULL);
+/**
+ * Updates _near_point, _next_way, and _next_wpt. If quick is FALSE (as
+ * it is when this function is called from route_find_nearest_point), then
+ * the entire list (starting from _near_point) is searched. Otherwise, we
+ * stop searching when we find a point that is farther away.
+ */
+static gboolean
+route_update_nears(gboolean quick)
+{
+ gboolean ret = FALSE;
+ Point *curr, *near;
+ WayPoint *wcurr, *wnext;
+ guint near_dist_rough;
+ printf("%s(%d)\n", __PRETTY_FUNCTION__, quick);
- /* Save Show Routes flag. */
- gconf_client_set_bool(gconf_client,
- GCONF_KEY_SHOWROUTES, _show_tracks & ROUTES_MASK, NULL);
+ /* If we have waypoints (_next_way != NULL), then determine the "next
+ * waypoint", which is defined as the waypoint after the nearest point,
+ * UNLESS we've passed that waypoint, in which case the waypoint after
+ * that waypoint becomes the "next" waypoint. */
+ if(_next_way)
+ {
+ /* First, set near_dist_rough with the new distance from _near_point. */
+ near = _near_point;
+ near_dist_rough = DISTANCE_ROUGH(_pos, *near);
- /* Save Show Velocity Vector flag. */
- gconf_client_set_bool(gconf_client,
- GCONF_KEY_SHOWVELVEC, _show_velvec, NULL);
+ /* Now, search _route for a closer point. If quick is TRUE, then we'll
+ * only search forward, only as long as we keep finding closer points.
+ */
+ for(curr = _near_point; curr++ != _route.tail; )
+ {
+ if(curr->unity)
+ {
+ guint dist_rough = DISTANCE_ROUGH(_pos, *curr);
+ if(dist_rough <= near_dist_rough)
+ {
+ near = curr;
+ near_dist_rough = dist_rough;
+ }
+ else if(quick)
+ break;
+ }
+ }
- /* Save Enable GPS flag. */
- gconf_client_set_bool(gconf_client,
- GCONF_KEY_ENABLE_GPS, _enable_gps, NULL);
+ /* Update _near_point. */
+ _near_point = near;
+ _near_point_dist_rough = near_dist_rough;
- /* Save Route Locations. */
- gconf_client_set_list(gconf_client,
- GCONF_KEY_ROUTE_LOCATIONS, GCONF_VALUE_STRING, _loc_list, NULL);
+ for(wnext = wcurr = _next_way; wcurr != _route.wtail; wcurr++)
+ {
+ if(wcurr->point < near
+ /* Okay, this else if expression warrants explanation. If the
+ * nearest track point happens to be a waypoint, then we want to
+ * check if we have "passed" that waypoint. To check this, we
+ * test the distance from _pos to the waypoint and from _pos to
+ * _next_wpt, and if the former is increasing and the latter is
+ * decreasing, then we have passed the waypoint, and thus we
+ * should skip it. Note that if there is no _next_wpt, then
+ * there is no next waypoint, so we do not skip it in that case. */
+ || (wcurr->point == near && quick
+ && (_next_wpt
+ && (DISTANCE_ROUGH(_pos, *near) > _next_way_dist_rough
+ && DISTANCE_ROUGH(_pos, *_next_wpt)
+ < _next_wpt_dist_rough))))
+ wnext = wcurr + 1;
+ else
+ break;
+ }
- /* Save GPS Info flag. */
- gconf_client_set_bool(gconf_client,
- GCONF_KEY_GPS_INFO, _gps_info, NULL);
+ if(wnext == _route.wtail && (wnext->point < near
+ || (wnext->point == near && quick
+ && (!_next_wpt
+ || (DISTANCE_ROUGH(_pos, *near) > _next_way_dist_rough
+ &&DISTANCE_ROUGH(_pos, *_next_wpt)
+ < _next_wpt_dist_rough)))))
+ {
+ _next_way = NULL;
+ _next_wpt = NULL;
+ _next_way_dist_rough = -1;
+ _next_wpt_dist_rough = -1;
+ ret = TRUE;
+ }
+ /* Only update _next_way (and consequently _next_wpt) if _next_way is
+ * different, and record that fact for return. */
+ else
+ {
+ if(!quick || _next_way != wnext)
+ {
+ _next_way = wnext;
+ _next_wpt = wnext->point;
+ if(_next_wpt == _route.tail)
+ _next_wpt = NULL;
+ else
+ {
+ while(!(++_next_wpt)->unity)
+ {
+ if(_next_wpt == _route.tail)
+ {
+ _next_wpt = NULL;
+ break;
+ }
+ }
+ }
+ ret = TRUE;
+ }
+ _next_way_dist_rough = DISTANCE_ROUGH(_pos, *wnext->point);
+ if(_next_wpt)
+ _next_wpt_dist_rough = DISTANCE_ROUGH(_pos, *_next_wpt);
+ }
+ }
- /* Save Colors. */
- sprintf(buffer, "#%02x%02x%02x",
- _color_mark.red >> 8,
- _color_mark.green >> 8,
- _color_mark.blue >> 8);
- gconf_client_set_string(gconf_client,
- GCONF_KEY_COLOR_MARK, buffer, NULL);
+ vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, ret);
+ return ret;
+}
- sprintf(buffer, "#%02x%02x%02x",
- _color_mark_velocity.red >> 8,
- _color_mark_velocity.green >> 8,
- _color_mark_velocity.blue >> 8);
- gconf_client_set_string(gconf_client,
- GCONF_KEY_COLOR_MARK_VELOCITY, buffer, NULL);
+/**
+ * Reset the _near_point data by searching the entire route for the nearest
+ * route point and waypoint.
+ */
+static void
+route_find_nearest_point()
+{
+ printf("%s()\n", __PRETTY_FUNCTION__);
- sprintf(buffer, "#%02x%02x%02x",
- _color_mark_old.red >> 8,
- _color_mark_old.green >> 8,
- _color_mark_old.blue >> 8);
- gconf_client_set_string(gconf_client,
- GCONF_KEY_COLOR_MARK_OLD, buffer, NULL);
+ /* Initialize _near_point. */
+ _near_point = _route.head;
+ while(!_near_point->unity && _near_point != _route.tail)
+ _near_point++;
- sprintf(buffer, "#%02x%02x%02x",
- _color_track.red >> 8,
- _color_track.green >> 8,
- _color_track.blue >> 8);
- gconf_client_set_string(gconf_client,
- GCONF_KEY_COLOR_TRACK, buffer, NULL);
+ /* Initialize _next_way. */
+ if(_route.wtail == _route.whead - 1
+ || (_autoroute_data.enabled && _route.wtail == _route.whead))
+ _next_way = NULL;
+ else
+ /* We have at least one waypoint. */
+ _next_way = (_autoroute_data.enabled ? _route.whead + 1 : _route.whead);
+ _next_way_dist_rough = -1;
- sprintf(buffer, "#%02x%02x%02x",
- _color_track_break.red >> 8,
- _color_track_break.green >> 8,
- _color_track_break.blue >> 8);
- gconf_client_set_string(gconf_client,
- GCONF_KEY_COLOR_TRACK_BREAK, buffer, NULL);
+ /* Initialize _next_wpt. */
+ _next_wpt = NULL;
+ _next_wpt_dist_rough = -1;
- sprintf(buffer, "#%02x%02x%02x",
- _color_route.red >> 8,
- _color_route.green >> 8,
- _color_route.blue >> 8);
- gconf_client_set_string(gconf_client,
- GCONF_KEY_COLOR_ROUTE, buffer, NULL);
+ route_update_nears(FALSE);
- sprintf(buffer, "#%02x%02x%02x",
- _color_route_way.red >> 8,
- _color_route_way.green >> 8,
- _color_route_way.blue >> 8);
- gconf_client_set_string(gconf_client,
- GCONF_KEY_COLOR_ROUTE_WAY, buffer, NULL);
-
- sprintf(buffer, "#%02x%02x%02x",
- _color_route_nextway.red >> 8,
- _color_route_nextway.green >> 8,
- _color_route_nextway.blue >> 8);
- gconf_client_set_string(gconf_client,
- GCONF_KEY_COLOR_ROUTE_NEXTWAY, buffer, NULL);
-
- sprintf(buffer, "#%02x%02x%02x",
- _color_poi.red >> 8,
- _color_poi.green >> 8,
- _color_poi.blue >> 8);
- gconf_client_set_string(gconf_client,
- GCONF_KEY_COLOR_POI, buffer, NULL);
-
- /* Save POI database. */
- if(_poi_db)
- gconf_client_set_string(gconf_client,
- GCONF_KEY_POI_DB, _poi_db, NULL);
- else
- gconf_client_unset(gconf_client, GCONF_KEY_POI_DB, NULL);
-
- /* Save Show POI below zoom. */
- gconf_client_set_int(gconf_client,
- GCONF_KEY_POI_ZOOM, _poi_zoom, NULL);
-
- g_object_unref(gconf_client);
-
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+/**
+ * Render a single track line to _map_pixmap. If either point on the line
+ * is a break (defined as unity == 0), a circle is drawn at the other point.
+ * IT IS AN ERROR FOR BOTH POINTS TO INDICATE A BREAK.
+ */
static void
-force_min_visible_bars(HildonControlbar *control_bar, gint num_bars)
-{
- GValue val;
- memset(&val, 0, sizeof(val));
- g_value_init(&val, G_TYPE_INT);
- g_value_set_int(&val, num_bars);
- g_object_set_property(G_OBJECT(control_bar), "minimum-visible-bars", &val);
-}
-
-
-typedef struct _ScanInfo ScanInfo;
-struct _ScanInfo {
- GtkWidget *settings_dialog;
- GtkWidget *txt_rcvr_mac;
- GtkWidget *scan_dialog;
- GtkWidget *banner;
- GtkListStore *store;
- guint sid;
-};
-
-static gboolean
-scan_bluetooth_idle(ScanInfo *scan_info)
+map_render_segment(GdkGC *gc_norm, GdkGC *gc_alt,
+ guint unitx1, guint unity1, guint unitx2, guint unity2)
{
- gint devid, num_rsp;
- GtkTreeIter iter;
- inquiry_info *ii = NULL;
-
- devid = hci_get_route(NULL);
-
- ii = (inquiry_info*)malloc(255 * sizeof(inquiry_info));
- num_rsp = hci_inquiry(devid, 4, 255, NULL, &ii, IREQ_CACHE_FLUSH);
+ vprintf("%s()\n", __PRETTY_FUNCTION__);
- if(num_rsp < 0)
+ if(!unity1)
{
- gtk_widget_destroy(scan_info->banner);
- gtk_widget_hide(scan_info->scan_dialog);
- popup_error(scan_info->settings_dialog,
- _("An error occurred while scanning."));
+ guint x2, y2;
+ x2 = unit2bufx(unitx2);
+ y2 = unit2bufy(unity2);
+ /* Make sure this circle will be visible. */
+ if((x2 < BUF_WIDTH_PIXELS)
+ && (y2 < BUF_HEIGHT_PIXELS))
+ gdk_draw_arc(_map_pixmap, gc_alt,
+ FALSE, /* FALSE: not filled. */
+ x2 - _draw_line_width,
+ y2 - _draw_line_width,
+ 2 * _draw_line_width,
+ 2 * _draw_line_width,
+ 0, /* start at 0 degrees. */
+ 360 * 64);
}
- else if(num_rsp == 0)
+ else if(!unity2)
{
- gtk_widget_destroy(scan_info->banner);
- gtk_widget_hide(scan_info->scan_dialog);
- popup_error(scan_info->settings_dialog,
- _("No bluetooth devices found."));
+ guint x1, y1;
+ x1 = unit2bufx(unitx1);
+ y1 = unit2bufy(unity1);
+ /* Make sure this circle will be visible. */
+ if((x1 < BUF_WIDTH_PIXELS)
+ && ((unsigned)y1 < BUF_HEIGHT_PIXELS))
+ gdk_draw_arc(_map_pixmap, gc_alt,
+ FALSE, /* FALSE: not filled. */
+ x1 - _draw_line_width,
+ y1 - _draw_line_width,
+ 2 * _draw_line_width,
+ 2 * _draw_line_width,
+ 0, /* start at 0 degrees. */
+ 360 * 64);
}
else
{
- guint i;
- gint sock = hci_open_dev(devid);
- for(i = 0; i < num_rsp; i++)
- {
- gchar addr[19] = { 0 };
- gchar name[256] = { 0 };
-
- ba2str(&ii[i].bdaddr, addr);
- memset(name, 0, sizeof(name));
- if(hci_read_remote_name(sock, &ii[i].bdaddr, sizeof(name), name, 0))
- strcpy(name, _("Unknown"));
-
- gtk_list_store_append(scan_info->store, &iter);
- gtk_list_store_set(scan_info->store, &iter,
- 0, g_strdup(addr),
- 1, g_strdup(name),
- -1);
- }
- close(sock);
- gtk_widget_destroy(scan_info->banner);
+ gint x1, y1, x2, y2;
+ x1 = unit2bufx(unitx1);
+ y1 = unit2bufy(unity1);
+ x2 = unit2bufx(unitx2);
+ y2 = unit2bufy(unity2);
+ /* Make sure this line could possibly be visible. */
+ if(!((x1 > BUF_WIDTH_PIXELS && x2 > BUF_WIDTH_PIXELS)
+ || (x1 < 0 && x2 < 0)
+ || (y1 > BUF_HEIGHT_PIXELS && y2 > BUF_HEIGHT_PIXELS)
+ || (y1 < 0 && y2 < 0)))
+ gdk_draw_line(_map_pixmap, gc_norm, x1, y1, x2, y2);
}
- free(ii);
- scan_info->sid = 0;
- return FALSE;
+
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
/**
- * Scan for all bluetooth devices. This method can take a few seconds,
- * during which the UI will freeze.
+ * Render all track data onto the _map_pixmap. Note that this does not
+ * clear the pixmap of previous track data (use map_force_redraw() for
+ * that), and also note that this method does not queue any redraws, so it
+ * is up to the caller to decide which part of the track really needs to be
+ * redrawn.
*/
-static gboolean
-scan_bluetooth(GtkWidget *widget, ScanInfo *scan_info)
+static void
+map_render_track()
{
- /* Do an hci_inquiry for our boy. */
- GtkWidget *dialog;
- GtkWidget *lst_devices;
- GtkTreeViewColumn *column;
- GtkCellRenderer *renderer;
+ TrackPoint *curr;
printf("%s()\n", __PRETTY_FUNCTION__);
- dialog = gtk_dialog_new_with_buttons(_("Select Bluetooth Device"),
- GTK_WINDOW(scan_info->settings_dialog), GTK_DIALOG_MODAL,
- GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
- GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
- NULL);
-
- scan_info->scan_dialog = dialog;
-
- scan_info->banner = hildon_banner_show_animation(dialog, NULL,
- _("Scanning Bluetooth Devices"));
-
- scan_info->store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
-
- scan_info->sid = g_idle_add((GSourceFunc)scan_bluetooth_idle, scan_info);
-
- gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 300);
-
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
- lst_devices = gtk_tree_view_new_with_model(
- GTK_TREE_MODEL(scan_info->store)), TRUE, TRUE, 0);
-
- g_object_unref(G_OBJECT(scan_info->store));
-
- gtk_tree_selection_set_mode(
- gtk_tree_view_get_selection(GTK_TREE_VIEW(lst_devices)),
- GTK_SELECTION_SINGLE);
- gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(lst_devices), TRUE);
-
- renderer = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(
- _("MAC"), renderer, "text", 0);
- gtk_tree_view_append_column(GTK_TREE_VIEW(lst_devices), column);
+ for(curr = _track.head; curr != _track.tail; curr++)
+ map_render_segment(_gc_track, _gc_track_break,
+ curr->point.unitx, curr->point.unity,
+ curr[1].point.unitx, curr[1].point.unity);
- renderer = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(
- _("Description"), renderer, "text", 1);
- gtk_tree_view_append_column(GTK_TREE_VIEW(lst_devices), column);
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
- gtk_widget_show_all(dialog);
+/**
+ * Render all track data onto the _map_pixmap. Note that this does not
+ * clear the pixmap of previous track data (use map_force_redraw() for
+ * that), and also note that this method does not queue any redraws, so it
+ * is up to the caller to decide which part of the track really needs to be
+ * redrawn.
+ */
+static void
+map_render_route()
+{
+ Point *curr;
+ WayPoint *wcurr;
+ printf("%s()\n", __PRETTY_FUNCTION__);
- while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
+ _visible_way_first = _visible_way_last = NULL;
+ for(curr = _route.head, wcurr = _route.whead; curr != _route.tail; curr++)
{
- GtkTreeIter iter;
- if(gtk_tree_selection_get_selected(
- gtk_tree_view_get_selection(GTK_TREE_VIEW(lst_devices)),
- NULL, &iter))
+ if(wcurr && wcurr <= _route.wtail && curr == wcurr->point)
{
- gchar *mac;
- gtk_tree_model_get(GTK_TREE_MODEL(scan_info->store),
- &iter, 0, &mac, -1);
- gtk_entry_set_text(GTK_ENTRY(scan_info->txt_rcvr_mac), mac);
- break;
+ guint x1 = unit2bufx(wcurr->point->unitx);
+ guint y1 = unit2bufy(wcurr->point->unity);
+ if((x1 < BUF_WIDTH_PIXELS)
+ && (y1 < BUF_HEIGHT_PIXELS))
+ {
+ gdk_draw_arc(_map_pixmap,
+ (wcurr==_next_way ? _gc_route_nextway : _gc_route_way),
+ FALSE, /* FALSE: not filled. */
+ x1 - _draw_line_width,
+ y1 - _draw_line_width,
+ 2 * _draw_line_width,
+ 2 * _draw_line_width,
+ 0, /* start at 0 degrees. */
+ 360 * 64);
+ if(!_visible_way_first)
+ _visible_way_first = wcurr;
+ _visible_way_last = wcurr;
+ }
+ wcurr++;
+ if(!curr[1].unity)
+ continue;
}
- else
- popup_error(dialog,
- _("Please select a bluetooth device from the list."));
+ map_render_segment(_gc_route, _gc_route_way,
+ curr->unitx, curr->unity, curr[1].unitx, curr[1].unity);
}
- if(scan_info->sid)
- g_source_remove(scan_info->sid);
- gtk_widget_destroy(dialog);
-
- vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
- return TRUE;
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
-typedef struct _BrowseInfo BrowseInfo;
-struct _BrowseInfo {
- GtkWidget *dialog;
- GtkWidget *txt;
-};
-
-static gboolean
-settings_dialog_browse_forfile(GtkWidget *widget, BrowseInfo *browse_info)
+static void
+map_render_paths()
{
- GtkWidget *dialog;
printf("%s()\n", __PRETTY_FUNCTION__);
- dialog = GTK_WIDGET(
- hildon_file_chooser_dialog_new(GTK_WINDOW(browse_info->dialog),
- GTK_FILE_CHOOSER_ACTION_OPEN));
+ if((_show_tracks & ROUTES_MASK) && _route.head)
+ {
+ map_render_route();
+ if(_next_way == NULL)
+ {
+ guint x1 = unit2bufx(_route.tail[-1].unitx);
+ guint y1 = unit2bufy(_route.tail[-1].unity);
+ if((x1 < BUF_WIDTH_PIXELS)
+ && (y1 < BUF_HEIGHT_PIXELS))
+ {
+ gdk_draw_arc(_map_pixmap,
+ _gc_route_nextway,
+ FALSE, /* FALSE: not filled. */
+ x1 - _draw_line_width,
+ y1 - _draw_line_width,
+ 2 * _draw_line_width,
+ 2 * _draw_line_width,
+ 0, /* start at 0 degrees. */
+ 360 * 64);
+ }
+ }
+ }
+ if(_show_tracks & TRACKS_MASK)
+ map_render_track();
- gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(dialog), TRUE);
- gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),
- gtk_entry_get_text(GTK_ENTRY(browse_info->txt)));
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
- if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(dialog)))
+/**
+ * Add a point to the _track list. This function is slightly overloaded,
+ * since it is what houses the check for "have we moved
+ * significantly": it also initiates the re-calculation of the _near_point
+ * data, as well as calling osso_display_state_on() when we have the focus.
+ *
+ * If a non-zero time is given, then the current position (as taken from the
+ * _pos variable) is appended to _track with the given time. If time is zero,
+ * then _pos_null is appended to _track with time zero (this produces a "break"
+ * in the track).
+ */
+static void
+track_add(time_t time, gboolean newly_fixed)
+{
+ Point pos = (time == 0 ? _pos_null : _pos);
+ printf("%s(%u, %u)\n", __PRETTY_FUNCTION__, pos.unitx, pos.unity);
+
+ if(abs((gint)pos.unitx - _track.tail->point.unitx) > _draw_line_width
+ || abs((gint)pos.unity - _track.tail->point.unity) > _draw_line_width)
{
- gchar *filename = gtk_file_chooser_get_filename(
- GTK_FILE_CHOOSER(dialog));
- gtk_entry_set_text(GTK_ENTRY(browse_info->txt), filename);
- g_free(filename);
- }
+ if(time && _route.head
+ && (newly_fixed ? (route_find_nearest_point(), TRUE)
+ : route_update_nears(TRUE)))
+ {
+ map_render_paths();
+ MACRO_QUEUE_DRAW_AREA();
+ }
+ if(_show_tracks & TRACKS_MASK)
+ {
+ /* Instead of calling map_render_paths(), we'll draw the new line
+ * ourselves and call gtk_widget_queue_draw_area(). */
+ gint tx1, ty1, tx2, ty2;
+ map_render_segment(_gc_track, _gc_track_break,
+ _track.tail->point.unitx, _track.tail->point.unity,
+ pos.unitx, pos.unity);
+ if(time && _track.tail->point.unity)
+ {
+ tx1 = unit2x(_track.tail->point.unitx);
+ ty1 = unit2y(_track.tail->point.unity);
+ tx2 = unit2x(pos.unitx);
+ ty2 = unit2y(pos.unity);
+ gtk_widget_queue_draw_area(_map_widget,
+ MIN(tx1, tx2) - _draw_line_width,
+ MIN(ty1, ty2) - _draw_line_width,
+ abs(tx1 - tx2) + (2 * _draw_line_width),
+ abs(ty1 - ty2) + (2 * _draw_line_width));
+ }
+ }
+ MACRO_TRACK_INCREMENT_TAIL(_track);
- gtk_widget_destroy(dialog);
+ _track.tail->point = pos;
+ _track.tail->time = time;
- vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
- return TRUE;
-}
+ if(_autoroute_data.enabled && !_autoroute_data.in_progress
+ && _near_point_dist_rough > 400)
+ {
+ _autoroute_data.in_progress = TRUE;
+ g_idle_add((GSourceFunc)auto_route_dl_idle, NULL);
+ }
+ /* Keep the display on. */
+ KEEP_DISPLAY_ON();
+ }
-typedef struct _ColorsDialogInfo ColorsDialogInfo;
-struct _ColorsDialogInfo {
- GtkWidget *col_mark;
- GtkWidget *col_mark_velocity;
- GtkWidget *col_mark_old;
- GtkWidget *col_track;
- GtkWidget *col_track_break;
- GtkWidget *col_route;
- GtkWidget *col_route_way;
- GtkWidget *col_route_nextway;
- GtkWidget *col_poi;
-};
+ /* Check if we should announce upcoming waypoints. */
+ if(time && _next_way_dist_rough
+ < (20 + (guint)_speed) * _announce_notice_ratio * 3)
+ {
+ if(_enable_voice && strcmp(_next_way->desc, _last_spoken_phrase))
+ {
+ g_free(_last_spoken_phrase);
+ _last_spoken_phrase = g_strdup(_next_way->desc);
+ if(!fork())
+ {
+ /* We are the fork child. Synthesize the voice. */
+ hildon_play_system_sound(
+ "/usr/share/sounds/ui-information_note.wav");
+ sleep(1);
+# define _voice_synth_path "/usr/bin/flite"
+ printf("%s %s\n", _voice_synth_path, _last_spoken_phrase);
+ execl(_voice_synth_path, _voice_synth_path,
+ "-t", _last_spoken_phrase, (char *)NULL);
+ exit(0);
+ }
+ }
+ hildon_banner_show_information(_window, NULL, _next_way->desc);
+ }
-static gboolean
-settings_dialog_colors_reset(GtkWidget *widget, ColorsDialogInfo *cdi)
-{
- hildon_color_button_set_color(
- HILDON_COLOR_BUTTON(cdi->col_mark),
- &DEFAULT_COLOR_MARK);
- hildon_color_button_set_color(
- HILDON_COLOR_BUTTON(cdi->col_mark_velocity),
- &DEFAULT_COLOR_MARK_VELOCITY);
- hildon_color_button_set_color(
- HILDON_COLOR_BUTTON(cdi->col_mark_old),
- &DEFAULT_COLOR_MARK_OLD);
- hildon_color_button_set_color(
- HILDON_COLOR_BUTTON(cdi->col_track),
- &DEFAULT_COLOR_TRACK);
- hildon_color_button_set_color(
- HILDON_COLOR_BUTTON(cdi->col_track_break),
- &DEFAULT_COLOR_TRACK_BREAK);
- hildon_color_button_set_color(
- HILDON_COLOR_BUTTON(cdi->col_route),
- &DEFAULT_COLOR_ROUTE);
- hildon_color_button_set_color(
- HILDON_COLOR_BUTTON(cdi->col_route_way),
- &DEFAULT_COLOR_ROUTE_WAY);
- hildon_color_button_set_color(
- HILDON_COLOR_BUTTON(cdi->col_route_nextway),
- &DEFAULT_COLOR_ROUTE_NEXTWAY);
- hildon_color_button_set_color(
- HILDON_COLOR_BUTTON(cdi->col_poi),
- &DEFAULT_COLOR_POI);
- return TRUE;
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
-static gboolean
-settings_dialog_colors(GtkWidget *widget, GtkWidget *parent)
+/**
+ * Disconnect from the receiver. This method cleans up any and everything
+ * that might be associated with the receiver.
+ */
+static void
+rcvr_disconnect()
{
- GtkWidget *dialog;
- GtkWidget *table;
- GtkWidget *label;
- GtkWidget *btn_defaults;
- ColorsDialogInfo cdi;
printf("%s()\n", __PRETTY_FUNCTION__);
- dialog = gtk_dialog_new_with_buttons(_("Colors"),
- GTK_WINDOW(parent), GTK_DIALOG_MODAL,
- GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
- NULL);
+ /* Remove watches. */
+ if(_clater_sid)
+ {
+ g_source_remove(_clater_sid);
+ _clater_sid = 0;
+ }
+ if(_error_sid)
+ {
+ g_source_remove(_error_sid);
+ _error_sid = 0;
+ }
+ if(_connect_sid)
+ {
+ g_source_remove(_connect_sid);
+ _connect_sid = 0;
+ }
+ if(_input_sid)
+ {
+ g_source_remove(_input_sid);
+ _input_sid = 0;
+ }
- gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
- btn_defaults = gtk_button_new_with_label(_("Defaults")));
- g_signal_connect(G_OBJECT(btn_defaults), "clicked",
- G_CALLBACK(settings_dialog_colors_reset), &cdi);
+ /* Destroy the GIOChannel object. */
+ if(_channel)
+ {
+ g_io_channel_shutdown(_channel, FALSE, NULL);
+ g_io_channel_unref(_channel);
+ _channel = NULL;
+ }
- gtk_dialog_add_button(GTK_DIALOG(dialog),
- GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
+ /* Close the file descriptor. */
+ if(_fd != -1)
+ {
+ close(_fd);
+ _fd = -1;
+ }
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
- table = gtk_table_new(4, 3, FALSE), TRUE, TRUE, 0);
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
- /* Mark. */
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(_("GPS Mark")),
- 0, 1, 0, 1, GTK_FILL, 0, 2, 4);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
- gtk_table_attach(GTK_TABLE(table),
- cdi.col_mark = hildon_color_button_new(),
- 1, 2, 0, 1, 0, 0, 2, 4);
- hildon_color_button_set_color(
- HILDON_COLOR_BUTTON(cdi.col_mark), &_color_mark);
- gtk_table_attach(GTK_TABLE(table),
- cdi.col_mark_velocity = hildon_color_button_new(),
- 2, 3, 0, 1, 0, 0, 2, 4);
- hildon_color_button_set_color(
- HILDON_COLOR_BUTTON(cdi.col_mark_velocity), &_color_mark_velocity);
- gtk_table_attach(GTK_TABLE(table),
- cdi.col_mark_old = hildon_color_button_new(),
- 3, 4, 0, 1, 0, 0, 2, 4);
- hildon_color_button_set_color(
- HILDON_COLOR_BUTTON(cdi.col_mark_old), &_color_mark_old);
-
- /* Track. */
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(_("Track")),
- 0, 1, 1, 2, GTK_FILL, 0, 2, 4);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
- gtk_table_attach(GTK_TABLE(table),
- cdi.col_track = hildon_color_button_new(),
- 1, 2, 1, 2, 0, 0, 2, 4);
- hildon_color_button_set_color(
- HILDON_COLOR_BUTTON(cdi.col_track), &_color_track);
- gtk_table_attach(GTK_TABLE(table),
- cdi.col_track_break = hildon_color_button_new(),
- 2, 3, 1, 2, 0, 0, 2, 4);
- hildon_color_button_set_color(
- HILDON_COLOR_BUTTON(cdi.col_track_break), &_color_track_break);
-
- /* Route. */
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(_("Route")),
- 0, 1, 2, 3, GTK_FILL, 0, 2, 4);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
- gtk_table_attach(GTK_TABLE(table),
- cdi.col_route = hildon_color_button_new(),
- 1, 2, 2, 3, 0, 0, 2, 4);
- hildon_color_button_set_color(
- HILDON_COLOR_BUTTON(cdi.col_route), &_color_route);
- gtk_table_attach(GTK_TABLE(table),
- cdi.col_route_way = hildon_color_button_new(),
- 2, 3, 2, 3, 0, 0, 2, 4);
- hildon_color_button_set_color(
- HILDON_COLOR_BUTTON(cdi.col_route_way), &_color_route_way);
- gtk_table_attach(GTK_TABLE(table),
- cdi.col_route_nextway = hildon_color_button_new(),
- 3, 4, 2, 3, 0, 0, 2, 4);
- hildon_color_button_set_color(
- HILDON_COLOR_BUTTON(cdi.col_route_nextway), &_color_route_nextway);
-
- /* POI. */
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(_("POI")),
- 0, 1, 3, 4, GTK_FILL, 0, 2, 4);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
- gtk_table_attach(GTK_TABLE(table),
- cdi.col_poi = hildon_color_button_new(),
- 1, 2, 3, 4, 0, 0, 2, 4);
- hildon_color_button_set_color(
- HILDON_COLOR_BUTTON(cdi.col_poi), &_color_poi);
-
- gtk_widget_show_all(dialog);
+static void rcvr_connect_later(); /* Forward declaration. */
- while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
- {
- GdkColor *color;
+/**
+ * Connect to the receiver.
+ * This method assumes that _fd is -1 and _channel is NULL. If unsure, call
+ * rcvr_disconnect() first.
+ * Since this is an idle function, this function returns whether or not it
+ * should be called again, which is always FALSE.
+ */
+static gboolean
+rcvr_connect_now()
+{
+ printf("%s(%d)\n", __PRETTY_FUNCTION__, _conn_state);
- color = hildon_color_button_get_color(
- HILDON_COLOR_BUTTON(cdi.col_mark));
- _color_mark = *color;
+ if(_conn_state == RCVR_DOWN && _rcvr_mac) {
+#ifndef DEBUG
+ /* Create the file descriptor. */
+ if(*_rcvr_mac == '/')
+ _fd = open(_rcvr_mac, O_RDONLY);
+ else
+ _fd = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
- color = hildon_color_button_get_color(
- HILDON_COLOR_BUTTON(cdi.col_mark_velocity));
- _color_mark_velocity = *color;
+ /* If file descriptor creation failed, try again later. Note that
+ * there is no need to call rcvr_disconnect() because the file
+ * descriptor creation is the first step, so if it fails, there's
+ * nothing to clean up. */
+ if(_fd == -1)
+ rcvr_connect_later();
+ else
+ {
+ /* Reset GPS read buffer */
+ _gps_read_buf_curr = _gps_read_buf;
+ *_gps_read_buf_curr = '\0';
- color = hildon_color_button_get_color(
- HILDON_COLOR_BUTTON(cdi.col_mark_old));
- _color_mark_old = *color;
+ /* Create channel and add watches. */
+ _channel = g_io_channel_unix_new(_fd);
+ g_io_channel_set_flags(_channel, G_IO_FLAG_NONBLOCK, NULL);
+ _error_sid = g_io_add_watch_full(_channel, G_PRIORITY_HIGH_IDLE,
+ G_IO_ERR | G_IO_HUP, channel_cb_error, NULL, NULL);
+ _connect_sid = g_io_add_watch_full(_channel, G_PRIORITY_HIGH_IDLE,
+ G_IO_OUT, channel_cb_connect, NULL, NULL);
+ if(*_rcvr_mac != '/'
+ && connect(_fd, (struct sockaddr*)&_rcvr_addr,
+ sizeof(_rcvr_addr))
+ && errno != EAGAIN)
+ {
+ /* Connection failed. Disconnect and try again later. */
+ rcvr_disconnect();
+ rcvr_connect_later();
+ }
+ }
+#else
+ /* We're in DEBUG mode, so instead of connecting, skip to FIXED. */
+ set_conn_state(RCVR_FIXED);
+#endif
+ }
- color = hildon_color_button_get_color(
- HILDON_COLOR_BUTTON(cdi.col_track));
- _color_track = *color;
+ _clater_sid = 0;
- color = hildon_color_button_get_color(
- HILDON_COLOR_BUTTON(cdi.col_track_break));
- _color_track_break = *color;
+ vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+ return FALSE;
+}
- color = hildon_color_button_get_color(
- HILDON_COLOR_BUTTON(cdi.col_route));
- _color_route = *color;
+/**
+ * Place a request to connect about 1 second after the function is called.
+ */
+static void
+rcvr_connect_later()
+{
+ printf("%s()\n", __PRETTY_FUNCTION__);
- color = hildon_color_button_get_color(
- HILDON_COLOR_BUTTON(cdi.col_route_way));
- _color_route_way = *color;
+ _clater_sid = g_timeout_add(1000, (GSourceFunc)rcvr_connect_now, NULL);
- color = hildon_color_button_get_color(
- HILDON_COLOR_BUTTON(cdi.col_route_nextway));
- _color_route_nextway = *color;
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
- color = hildon_color_button_get_color(
- HILDON_COLOR_BUTTON(cdi.col_poi));
- _color_poi = *color;
+/**
+ * Convert the float lat/lon/speed/heading data into integer units.
+ */
+static void
+integerize_data()
+{
+ gfloat tmp;
+ printf("%s()\n", __PRETTY_FUNCTION__);
- update_gcs();
- break;
- }
+ latlon2unit(_pos_lat, _pos_lon, _pos.unitx, _pos.unity);
- gtk_widget_destroy(dialog);
+ tmp = (_heading * (1.f / 180.f)) * PI;
+ _vel_offsetx = (gint)(floorf(_speed * sinf(tmp) + 0.5f));
+ _vel_offsety = -(gint)(floorf(_speed * cosf(tmp) + 0.5f));
- vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
- return TRUE;
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
/**
- * Bring up the Settings dialog. Return TRUE if and only if the recever
- * information has changed (MAC or channel).
+ * Update all GdkGC objects to reflect the current _draw_line_width.
*/
-static gboolean
-settings_dialog()
+#define UPDATE_GC(gc) \
+ gdk_gc_set_line_attributes(gc, \
+ _draw_line_width, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
+static void
+update_gcs()
{
- GtkWidget *dialog;
- GtkWidget *notebook;
- GtkWidget *table;
- GtkWidget *hbox;
- GtkWidget *hbox2;
- GtkWidget *label;
- GtkWidget *txt_rcvr_mac;
- GtkWidget *num_rcvr_chan;
- GtkWidget *num_center_ratio;
- GtkWidget *num_lead_ratio;
- GtkWidget *num_announce_notice;
- GtkWidget *chk_enable_voice;
- GtkWidget *num_voice_speed;
- GtkWidget *num_voice_pitch;
- GtkWidget *num_draw_line_width;
- GtkWidget *chk_always_keep_on;
- GtkWidget *cmb_units;
- GtkWidget *cmb_escape_key;
- GtkWidget *btn_scan;
- GtkWidget *btn_colors;
-
- GtkWidget *txt_poi_db;
- GtkWidget *btn_browsepoi;
- GtkWidget *num_poi_zoom;
-
- BrowseInfo browse_info = {0, 0};
- ScanInfo scan_info = {0};
- gboolean rcvr_changed = FALSE;
- guint i;
printf("%s()\n", __PRETTY_FUNCTION__);
- dialog = gtk_dialog_new_with_buttons(_("Maemo Mapper Settings"),
- GTK_WINDOW(_window), GTK_DIALOG_MODAL,
- GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
- NULL);
+ gdk_color_alloc(gtk_widget_get_colormap(_map_widget),
+ &_color_mark);
+ gdk_color_alloc(gtk_widget_get_colormap(_map_widget),
+ &_color_mark_velocity);
+ gdk_color_alloc(gtk_widget_get_colormap(_map_widget),
+ &_color_mark_old);
+ gdk_color_alloc(gtk_widget_get_colormap(_map_widget),
+ &_color_track);
+ gdk_color_alloc(gtk_widget_get_colormap(_map_widget),
+ &_color_track_break);
+ gdk_color_alloc(gtk_widget_get_colormap(_map_widget),
+ &_color_route);
+ gdk_color_alloc(gtk_widget_get_colormap(_map_widget),
+ &_color_route_way);
+ gdk_color_alloc(gtk_widget_get_colormap(_map_widget),
+ &_color_route_nextway);
+ gdk_color_alloc(gtk_widget_get_colormap(_map_widget),
+ &_color_poi);
- gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
- btn_colors = gtk_button_new_with_label(_("Colors...")));
+ if(_gc_mark)
+ {
+ g_object_unref(_gc_mark);
+ g_object_unref(_gc_mark_velocity);
+ g_object_unref(_gc_mark_old);
+ g_object_unref(_gc_track);
+ g_object_unref(_gc_track_break);
+ g_object_unref(_gc_route);
+ g_object_unref(_gc_route_way);
+ g_object_unref(_gc_route_nextway);
+ g_object_unref(_gc_poi);
+ }
- gtk_dialog_add_button(GTK_DIALOG(dialog),
- GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
+ /* _gc_mark is used to draw the mark when data is current. */
+ _gc_mark = gdk_gc_new(_map_pixmap);
+ gdk_gc_set_foreground(_gc_mark, &_color_mark);
+ gdk_gc_set_line_attributes(_gc_mark,
+ _draw_line_width, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
- notebook = gtk_notebook_new(), TRUE, TRUE, 0);
+ /* _gc_mark_old is used to draw the mark when data is old. */
+ _gc_mark_old = gdk_gc_new(_map_pixmap);
+ gdk_gc_set_foreground(_gc_mark_old, &_color_mark_old);
+ gdk_gc_set_line_attributes(_gc_mark_old,
+ _draw_line_width, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
- /* Receiver page. */
- gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
- table = gtk_table_new(2, 3, FALSE),
- label = gtk_label_new(_("GPS")));
+ /* _gc_mark_velocity is used to draw the vel_current line. */
+ _gc_mark_velocity = gdk_gc_new(_map_pixmap);
+ gdk_gc_set_foreground(_gc_mark_velocity, &_color_mark_velocity);
+ gdk_gc_set_line_attributes(_gc_mark_velocity,
+ _draw_line_width, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
- /* Receiver MAC Address. */
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(_("MAC")),
- 0, 1, 0, 1, GTK_FILL, 0, 2, 4);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
- gtk_table_attach(GTK_TABLE(table),
- hbox = gtk_hbox_new(FALSE, 4),
- 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
- gtk_box_pack_start(GTK_BOX(hbox),
- txt_rcvr_mac = gtk_entry_new(),
- TRUE, TRUE, 0);
- gtk_box_pack_start(GTK_BOX(hbox),
- btn_scan = gtk_button_new_with_label(_("Scan...")),
- FALSE, FALSE, 0);
+ /* _gc_track is used to draw the track line. */
+ _gc_track = gdk_gc_new(_map_pixmap);
+ gdk_gc_set_foreground(_gc_track, &_color_track);
+ gdk_gc_set_line_attributes(_gc_track,
+ _draw_line_width, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
- /* Receiver Channel. */
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(_("Channel")),
- 0, 1, 1, 2, GTK_FILL, 0, 2, 4);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
- 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
- gtk_container_add(GTK_CONTAINER(label),
- num_rcvr_chan = hildon_number_editor_new(0, 255));
+ /* _gc_track_break is used to draw the track_break dots. */
+ _gc_track_break = gdk_gc_new(_map_pixmap);
+ gdk_gc_set_foreground(_gc_track_break, &_color_track_break);
+ gdk_gc_set_line_attributes(_gc_track_break,
+ _draw_line_width, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
- /* Note!. */
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(
- _("Note: \"Channel\" refers to the device side!")),
- 0, 2, 2, 3, GTK_FILL, 0, 2, 4);
- gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
- gtk_misc_set_alignment(GTK_MISC(label), 0.5f, 0.5f);
+ /* _gc_route is used to draw the route line. */
+ _gc_route = gdk_gc_new(_map_pixmap);
+ gdk_gc_set_foreground(_gc_route, &_color_route);
+ gdk_gc_set_line_attributes(_gc_route,
+ _draw_line_width, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
+ /* _way_gc is used to draw the waypoint dots. */
+ _gc_route_way = gdk_gc_new(_map_pixmap);
+ gdk_gc_set_foreground(_gc_route_way, &_color_route_way);
+ gdk_gc_set_line_attributes(_gc_route_way,
+ _draw_line_width, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
- /* Auto-Center page. */
- gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
- table = gtk_table_new(2, 2, FALSE),
- label = gtk_label_new(_("Auto-Center")));
+ /* _gc_route_nextway is used to draw the next_way labels. */
+ _gc_route_nextway = gdk_gc_new(_map_pixmap);
+ gdk_gc_set_foreground(_gc_route_nextway, &_color_route_nextway);
+ gdk_gc_set_line_attributes(_gc_route_nextway,
+ _draw_line_width, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
- /* Auto-Center Sensitivity. */
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(_("Sensitivity")),
- 0, 1, 0, 1, GTK_FILL, 0, 2, 4);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
- 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
- gtk_container_add(GTK_CONTAINER(label),
- num_center_ratio = hildon_controlbar_new());
- hildon_controlbar_set_range(HILDON_CONTROLBAR(num_center_ratio), 1, 10);
- force_min_visible_bars(HILDON_CONTROLBAR(num_center_ratio), 1);
+ /* _gc_poi is used to draw the default POI icon. */
+ _gc_poi = gdk_gc_new(_map_pixmap);
+ gdk_gc_set_foreground(_gc_poi, &_color_poi);
+ gdk_gc_set_background(_gc_poi, &_color_poi);
+ gdk_gc_set_line_attributes(_gc_poi,
+ _draw_line_width, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
- /* Lead Amount. */
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(_("Lead Amount")),
- 0, 1, 1, 2, GTK_FILL, 0, 2, 4);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
- 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
- gtk_container_add(GTK_CONTAINER(label),
- num_lead_ratio = hildon_controlbar_new());
- hildon_controlbar_set_range(HILDON_CONTROLBAR(num_lead_ratio), 1, 10);
- force_min_visible_bars(HILDON_CONTROLBAR(num_lead_ratio), 1);
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
- /* Announcement. */
- gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
- table = gtk_table_new(2, 3, FALSE),
- label = gtk_label_new(_("Announce")));
+/**
+ * Save all configuration data to GCONF.
+ */
+static void
+config_save()
+{
+ GConfClient *gconf_client = gconf_client_get_default();
+ gchar buffer[16];
+ printf("%s()\n", __PRETTY_FUNCTION__);
- /* Announcement Advance Notice. */
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(_("Advance Notice")),
- 0, 1, 0, 1, GTK_FILL, 0, 2, 4);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
- gtk_table_attach(GTK_TABLE(table),
- num_announce_notice = hildon_controlbar_new(),
- 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
- hildon_controlbar_set_range(HILDON_CONTROLBAR(num_announce_notice), 1, 20);
- force_min_visible_bars(HILDON_CONTROLBAR(num_announce_notice), 1);
+ if(!gconf_client)
+ {
+ popup_error(_window,
+ _("Failed to initialize GConf. Settings were not saved."));
+ return;
+ }
- /* Enable Voice. */
- gtk_table_attach(GTK_TABLE(table),
- chk_enable_voice = gtk_check_button_new_with_label(
- _("Enable Voice Synthesis (requires flite)")),
- 0, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chk_enable_voice),
- _enable_voice);
+ /* Save Receiver MAC from GConf. */
+ if(_rcvr_mac)
+ gconf_client_set_string(gconf_client,
+ GCONF_KEY_RCVR_MAC, _rcvr_mac, NULL);
+ else
+ gconf_client_unset(gconf_client,
+ GCONF_KEY_RCVR_MAC, NULL);
- /* Voice Speed and Pitch. */
- gtk_table_attach(GTK_TABLE(table),
- hbox = gtk_hbox_new(FALSE, 12),
- 0, 2, 2, 3, 0, 0, 2, 6);
- gtk_box_pack_start(GTK_BOX(hbox),
- hbox2 = gtk_hbox_new(FALSE, 4),
- TRUE, TRUE, 4);
- gtk_box_pack_start(GTK_BOX(hbox2),
- label = gtk_label_new(_("Speed")),
- TRUE, TRUE, 0);
- gtk_box_pack_start(GTK_BOX(hbox2),
- num_voice_speed = hildon_controlbar_new(),
- TRUE, TRUE, 0);
- hildon_controlbar_set_range(HILDON_CONTROLBAR(num_voice_speed), 1, 10);
- force_min_visible_bars(HILDON_CONTROLBAR(num_voice_speed), 1);
+ /* Save Receiver Channel to GConf. */
+ gconf_client_set_int(gconf_client,
+ GCONF_KEY_RCVR_CHAN, _rcvr_addr.rc_channel, NULL);
- gtk_box_pack_start(GTK_BOX(hbox),
- hbox2 = gtk_hbox_new(FALSE, 4),
- TRUE, TRUE, 4);
- gtk_box_pack_start(GTK_BOX(hbox2),
- label = gtk_label_new(_("Pitch")),
- TRUE, TRUE, 0);
- gtk_box_pack_start(GTK_BOX(hbox2),
- num_voice_pitch = hildon_controlbar_new(),
- TRUE, TRUE, 0);
- hildon_controlbar_set_range(HILDON_CONTROLBAR(num_voice_pitch), -2, 8);
- force_min_visible_bars(HILDON_CONTROLBAR(num_voice_pitch), 1);
+ /* Save Map Download URI Format. */
+ gconf_client_set_string(gconf_client,
+ GCONF_KEY_MAP_URI_FORMAT, _curr_repo->url, NULL);
- /* Misc. page. */
- gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
- table = gtk_table_new(2, 3, FALSE),
- label = gtk_label_new(_("Misc.")));
+ /* Save Map Download Zoom Steps. */
+ gconf_client_set_int(gconf_client,
+ GCONF_KEY_MAP_ZOOM_STEPS, _curr_repo->dl_zoom_steps, NULL);
- /* Line Width. */
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(_("Line Width")),
- 0, 1, 0, 1, GTK_FILL, 0, 2, 4);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
- gtk_table_attach(GTK_TABLE(table),
- num_draw_line_width = hildon_controlbar_new(),
- 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
- hildon_controlbar_set_range(HILDON_CONTROLBAR(num_draw_line_width), 1, 20);
- force_min_visible_bars(HILDON_CONTROLBAR(num_draw_line_width), 1);
+ /* Save Map Cache Directory. */
+ if(_curr_repo->cache_dir)
+ gconf_client_set_string(gconf_client,
+ GCONF_KEY_MAP_DIR_NAME, _curr_repo->cache_dir, NULL);
- /* Keep Display On Only When Fullscreen. */
- gtk_table_attach(GTK_TABLE(table),
- chk_always_keep_on = gtk_check_button_new_with_label(
- _("Keep Display On Only in Fullscreen Mode")),
- 0, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+ /* Save Auto-Download. */
+ gconf_client_set_bool(gconf_client,
+ GCONF_KEY_AUTO_DOWNLOAD, _auto_download, NULL);
- /* Units. */
- gtk_table_attach(GTK_TABLE(table),
- hbox = gtk_hbox_new(FALSE, 4),
- 0, 2, 2, 3, GTK_FILL, 0, 2, 4);
- gtk_box_pack_start(GTK_BOX(hbox),
- label = gtk_label_new(_("Units")),
- FALSE, FALSE, 0);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
- gtk_box_pack_start(GTK_BOX(hbox),
- label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
- TRUE, TRUE, 0);
- gtk_container_add(GTK_CONTAINER(label),
- cmb_units = gtk_combo_box_new_text());
- for(i = 0; i < UNITS_ENUM_COUNT; i++)
- gtk_combo_box_append_text(GTK_COMBO_BOX(cmb_units), UNITS_TEXT[i]);
+ /* Save Auto-Center Sensitivity. */
+ gconf_client_set_int(gconf_client,
+ GCONF_KEY_CENTER_SENSITIVITY, _center_ratio, NULL);
- /* Escape Key. */
- gtk_box_pack_start(GTK_BOX(hbox),
- label = gtk_label_new(_("Escape Key")),
- FALSE, FALSE, 0);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
- gtk_box_pack_start(GTK_BOX(hbox),
- label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
- TRUE, TRUE, 0);
- gtk_container_add(GTK_CONTAINER(label),
- cmb_escape_key = gtk_combo_box_new_text());
- for(i = 0; i < ESCAPE_KEY_ENUM_COUNT; i++)
- gtk_combo_box_append_text(GTK_COMBO_BOX(cmb_escape_key),
- ESCAPE_KEY_TEXT[i]);
+ /* Save Auto-Center Lead Amount. */
+ gconf_client_set_int(gconf_client,
+ GCONF_KEY_LEAD_AMOUNT, _lead_ratio, NULL);
- /* POI page */
- gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
- table = gtk_table_new(2, 3, FALSE),
- label = gtk_label_new(_("POI")));
+ /* Save Draw Line Width. */
+ gconf_client_set_int(gconf_client,
+ GCONF_KEY_DRAW_LINE_WIDTH, _draw_line_width, NULL);
- /* POI database. */
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(_("POI database")),
- 0, 1, 1, 2, GTK_FILL, 0, 2, 4);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
- gtk_table_attach(GTK_TABLE(table),
- hbox = gtk_hbox_new(FALSE, 4),
- 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
- gtk_box_pack_start(GTK_BOX(hbox),
- txt_poi_db = gtk_entry_new(),
- TRUE, TRUE, 0);
- gtk_box_pack_start(GTK_BOX(hbox),
- btn_browsepoi = gtk_button_new_with_label(_("Browse...")),
- FALSE, FALSE, 0);
+ /* Save Announce Advance Notice Ratio. */
+ gconf_client_set_int(gconf_client,
+ GCONF_KEY_ANNOUNCE_NOTICE, _announce_notice_ratio, NULL);
- /* Show POI below zoom. */
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_label_new(_("Show POI below zoom")),
- 0, 1, 2, 3, GTK_FILL, 0, 2, 4);
- gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
- gtk_table_attach(GTK_TABLE(table),
- label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
- 1, 2, 2, 3, GTK_EXPAND | GTK_FILL, 0, 2, 4);
- gtk_container_add(GTK_CONTAINER(label),
- num_poi_zoom = hildon_number_editor_new(0, MAX_ZOOM));
+ /* Save Enable Voice flag. */
+ gconf_client_set_bool(gconf_client,
+ GCONF_KEY_ENABLE_VOICE, _enable_voice, NULL);
+ /* Save Keep On When Fullscreen flag. */
+ gconf_client_set_bool(gconf_client,
+ GCONF_KEY_ALWAYS_KEEP_ON, _always_keep_on, NULL);
- /* Connect signals. */
- scan_info.settings_dialog = dialog;
- scan_info.txt_rcvr_mac = txt_rcvr_mac;
- g_signal_connect(G_OBJECT(btn_scan), "clicked",
- G_CALLBACK(scan_bluetooth), &scan_info);
- g_signal_connect(G_OBJECT(btn_colors), "clicked",
- G_CALLBACK(settings_dialog_colors), dialog);
+ /* Save Units. */
+ gconf_client_set_string(gconf_client,
+ GCONF_KEY_UNITS, UNITS_TEXT[_units], NULL);
- browse_info.dialog = dialog;
- browse_info.txt = txt_poi_db;
- g_signal_connect(G_OBJECT(btn_browsepoi), "clicked",
- G_CALLBACK(settings_dialog_browse_forfile), &browse_info);
+ /* Save Escape Key Function. */
+ gconf_client_set_string(gconf_client,
+ GCONF_KEY_ESCAPE_KEY, ESCAPE_KEY_TEXT[_escape_key], NULL);
- /* Initialize fields. */
- if(_rcvr_mac)
- gtk_entry_set_text(GTK_ENTRY(txt_rcvr_mac), _rcvr_mac);
- hildon_number_editor_set_value(HILDON_NUMBER_EDITOR(num_rcvr_chan),
- _rcvr_addr.rc_channel);
- if(_poi_db)
- gtk_entry_set_text(GTK_ENTRY(txt_poi_db), _poi_db);
- hildon_number_editor_set_value(HILDON_NUMBER_EDITOR(num_poi_zoom),
- _poi_zoom);
- hildon_controlbar_set_value(HILDON_CONTROLBAR(num_center_ratio),
- _center_ratio);
- hildon_controlbar_set_value(HILDON_CONTROLBAR(num_lead_ratio),
- _lead_ratio);
- hildon_controlbar_set_value(HILDON_CONTROLBAR(num_announce_notice),
- _announce_notice_ratio);
- hildon_controlbar_set_value(HILDON_CONTROLBAR(num_voice_speed),
- (gint)(_voice_speed * 3 + 0.5));
- hildon_controlbar_set_value(HILDON_CONTROLBAR(num_voice_pitch),
- _voice_pitch);
- hildon_controlbar_set_value(HILDON_CONTROLBAR(num_draw_line_width),
- _draw_line_width);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chk_always_keep_on),
- !_always_keep_on);
- gtk_combo_box_set_active(GTK_COMBO_BOX(cmb_units), _units);
- gtk_combo_box_set_active(GTK_COMBO_BOX(cmb_escape_key), _escape_key);
+ /* Save last saved latitude. */
+ gconf_client_set_float(gconf_client,
+ GCONF_KEY_LAT, _pos_lat, NULL);
- gtk_widget_show_all(dialog);
+ /* Save last saved longitude. */
+ gconf_client_set_float(gconf_client,
+ GCONF_KEY_LON, _pos_lon, NULL);
- while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
+ /* Save last center point. */
{
- /* Set _rcvr_mac if necessary. */
- if(!*gtk_entry_get_text(GTK_ENTRY(txt_rcvr_mac)))
- {
- /* User specified no rcvr mac - set _rcvr_mac to NULL. */
- if(_rcvr_mac)
- {
- g_free(_rcvr_mac);
- _rcvr_mac = NULL;
- rcvr_changed = TRUE;
- gtk_widget_set_sensitive(
- GTK_WIDGET(_menu_gps_details_item), FALSE);
- }
- if(_enable_gps)
- {
- gtk_check_menu_item_set_active(
- GTK_CHECK_MENU_ITEM(_menu_enable_gps_item), FALSE);
- popup_error(dialog, _("No GPS Receiver MAC Provided.\n"
- "GPS Disabled."));
- rcvr_changed = TRUE;
- gtk_widget_set_sensitive(GTK_WIDGET(_menu_gps_details_item),
- FALSE);
- gtk_widget_set_sensitive(GTK_WIDGET(_menu_gps_reset_item),
- FALSE);
- }
- }
- else if(!_rcvr_mac || strcmp(_rcvr_mac,
- gtk_entry_get_text(GTK_ENTRY(txt_rcvr_mac))))
- {
- /* User specified a new rcvr mac. */
- g_free(_rcvr_mac);
- _rcvr_mac = g_strdup(gtk_entry_get_text(GTK_ENTRY(txt_rcvr_mac)));
- str2ba(_rcvr_mac, &_rcvr_addr.rc_bdaddr);
- rcvr_changed = TRUE;
- }
+ gfloat center_lat, center_lon;
+ unit2latlon(_center.unitx, _center.unity, center_lat, center_lon);
- if(_rcvr_addr.rc_channel != hildon_number_editor_get_value(
- HILDON_NUMBER_EDITOR(num_rcvr_chan)))
- {
- _rcvr_addr.rc_channel = hildon_number_editor_get_value(
- HILDON_NUMBER_EDITOR(num_rcvr_chan));
- rcvr_changed = TRUE;
- }
+ /* Save last center latitude. */
+ gconf_client_set_float(gconf_client,
+ GCONF_KEY_CENTER_LAT, center_lat, NULL);
- _center_ratio = hildon_controlbar_get_value(
- HILDON_CONTROLBAR(num_center_ratio));
+ /* Save last center longitude. */
+ gconf_client_set_float(gconf_client,
+ GCONF_KEY_CENTER_LON, center_lon, NULL);
+ }
- _lead_ratio = hildon_controlbar_get_value(
- HILDON_CONTROLBAR(num_lead_ratio));
+ /* Save last Zoom Level. */
+ gconf_client_set_int(gconf_client,
+ GCONF_KEY_ZOOM, _zoom, NULL);
- _draw_line_width = hildon_controlbar_get_value(
- HILDON_CONTROLBAR(num_draw_line_width));
+ /* Save Route Directory. */
+ if(_route_dir_uri)
+ gconf_client_set_string(gconf_client,
+ GCONF_KEY_ROUTEDIR, _route_dir_uri, NULL);
- _always_keep_on = !gtk_toggle_button_get_active(
- GTK_TOGGLE_BUTTON(chk_always_keep_on));
+ /* Save the repositories. */
+ {
+ GList *curr = _repo_list;
+ GSList *temp_list = NULL;
+ gint curr_repo_index = 0;
- _units = gtk_combo_box_get_active(GTK_COMBO_BOX(cmb_units));
- _escape_key = gtk_combo_box_get_active(GTK_COMBO_BOX(cmb_escape_key));
+ for(curr = _repo_list; curr != NULL; curr = curr->next)
+ {
+ /* Build from each part of a repo, delimited by newline characters:
+ * 1. url
+ * 2. cache_dir
+ * 3. dl_zoom_steps
+ * 4. view_zoom_steps
+ */
+ RepoData *rd = curr->data;
+ gchar buffer[1024];
+ sprintf(buffer, "%s\n%s\n%s\n%d\n%d\n",
+ rd->name,
+ rd->url,
+ rd->cache_dir,
+ rd->dl_zoom_steps,
+ rd->view_zoom_steps);
+ temp_list = g_slist_append(temp_list, g_strdup(buffer));
+ if(rd == _curr_repo)
+ gconf_client_set_int(gconf_client,
+ GCONF_KEY_CURRREPO, curr_repo_index, NULL);
+ curr_repo_index++;
+ }
+ gconf_client_set_list(gconf_client,
+ GCONF_KEY_REPOSITORIES, GCONF_VALUE_STRING, temp_list, NULL);
+ }
- _announce_notice_ratio = hildon_controlbar_get_value(
- HILDON_CONTROLBAR(num_announce_notice));
+ /* Save Last Track File. */
+ if(_track_file_uri)
+ gconf_client_set_string(gconf_client,
+ GCONF_KEY_TRACKFILE, _track_file_uri, NULL);
- _voice_speed = hildon_controlbar_get_value(
- HILDON_CONTROLBAR(num_voice_speed)) / 3.0;
+ /* Save Auto-Center Mode. */
+ gconf_client_set_int(gconf_client,
+ GCONF_KEY_AUTOCENTER_MODE, _center_mode, NULL);
- _voice_pitch = hildon_controlbar_get_value(
- HILDON_CONTROLBAR(num_voice_pitch));
+ /* Save Show Tracks flag. */
+ gconf_client_set_bool(gconf_client,
+ GCONF_KEY_SHOWTRACKS, _show_tracks & TRACKS_MASK, NULL);
- _enable_voice = gtk_toggle_button_get_active(
- GTK_TOGGLE_BUTTON(chk_enable_voice));
+ /* Save Show Routes flag. */
+ gconf_client_set_bool(gconf_client,
+ GCONF_KEY_SHOWROUTES, _show_tracks & ROUTES_MASK, NULL);
- if(_dbconn)
- {
- sqlite_close(_db);
- _dbconn = FALSE;
- gtk_widget_set_sensitive(_cmenu_add_poi, FALSE);
- gtk_widget_set_sensitive(_cmenu_edit_poi, FALSE);
- gtk_widget_set_sensitive(_menu_poi_item, FALSE);
- }
- g_free(_poi_db);
- if(strlen(gtk_entry_get_text(GTK_ENTRY(txt_poi_db))))
- {
- _poi_db = g_strdup(gtk_entry_get_text(GTK_ENTRY(txt_poi_db)));
- db_connect();
- gtk_widget_set_sensitive(_cmenu_add_poi, _dbconn);
- gtk_widget_set_sensitive(_cmenu_edit_poi, _dbconn);
- gtk_widget_set_sensitive(_menu_poi_item, _dbconn);
- }
- else
- _poi_db = NULL;
+ /* Save Show Velocity Vector flag. */
+ gconf_client_set_bool(gconf_client,
+ GCONF_KEY_SHOWVELVEC, _show_velvec, NULL);
- _poi_zoom = hildon_number_editor_get_value(
- HILDON_NUMBER_EDITOR(num_poi_zoom));
+ /* Save Enable GPS flag. */
+ gconf_client_set_bool(gconf_client,
+ GCONF_KEY_ENABLE_GPS, _enable_gps, NULL);
- update_gcs();
+ /* Save Route Locations. */
+ gconf_client_set_list(gconf_client,
+ GCONF_KEY_ROUTE_LOCATIONS, GCONF_VALUE_STRING, _loc_list, NULL);
- config_save();
- break;
- }
+ /* Save GPS Info flag. */
+ gconf_client_set_bool(gconf_client,
+ GCONF_KEY_GPS_INFO, _gps_info, NULL);
- gtk_widget_hide(dialog); /* Destroying causes a crash (!?!?!??!) */
+ /* Save Route Download Radius. */
+ gconf_client_set_int(gconf_client,
+ GCONF_KEY_ROUTE_DL_RADIUS, _route_dl_radius, NULL);
- vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, rcvr_changed);
- return rcvr_changed;
-}
+ /* Save Colors. */
+ sprintf(buffer, "#%02x%02x%02x",
+ _color_mark.red >> 8,
+ _color_mark.green >> 8,
+ _color_mark.blue >> 8);
+ gconf_client_set_string(gconf_client,
+ GCONF_KEY_COLOR_MARK, buffer, NULL);
-/**
- * Initialize all configuration from GCONF. This should not be called more
- * than once during execution.
- */
-static void
-config_init()
-{
- GConfValue *value;
- GConfClient *gconf_client = gconf_client_get_default();
- gchar *str;
- printf("%s()\n", __PRETTY_FUNCTION__);
+ sprintf(buffer, "#%02x%02x%02x",
+ _color_mark_velocity.red >> 8,
+ _color_mark_velocity.green >> 8,
+ _color_mark_velocity.blue >> 8);
+ gconf_client_set_string(gconf_client,
+ GCONF_KEY_COLOR_MARK_VELOCITY, buffer, NULL);
- if(!gconf_client)
- {
- popup_error(_window, _("Failed to initialize GConf. Quitting."));
- exit(1);
- }
+ sprintf(buffer, "#%02x%02x%02x",
+ _color_mark_old.red >> 8,
+ _color_mark_old.green >> 8,
+ _color_mark_old.blue >> 8);
+ gconf_client_set_string(gconf_client,
+ GCONF_KEY_COLOR_MARK_OLD, buffer, NULL);
- /* Get Receiver MAC from GConf. Default is scanned via hci_inquiry. */
- {
- _rcvr_mac = gconf_client_get_string(
- gconf_client, GCONF_KEY_RCVR_MAC, NULL);
- if(_rcvr_mac)
- str2ba(_rcvr_mac, &_rcvr_addr.rc_bdaddr);
- }
+ sprintf(buffer, "#%02x%02x%02x",
+ _color_track.red >> 8,
+ _color_track.green >> 8,
+ _color_track.blue >> 8);
+ gconf_client_set_string(gconf_client,
+ GCONF_KEY_COLOR_TRACK, buffer, NULL);
- /* Get Receiver Channel from GConf. Default is 1. */
- _rcvr_addr.rc_family = AF_BLUETOOTH;
- _rcvr_addr.rc_channel = gconf_client_get_int(gconf_client,
- GCONF_KEY_RCVR_CHAN, NULL);
- if(_rcvr_addr.rc_channel < 1)
- _rcvr_addr.rc_channel = 1;
+ sprintf(buffer, "#%02x%02x%02x",
+ _color_track_break.red >> 8,
+ _color_track_break.green >> 8,
+ _color_track_break.blue >> 8);
+ gconf_client_set_string(gconf_client,
+ GCONF_KEY_COLOR_TRACK_BREAK, buffer, NULL);
- /* Get Auto-Download. Default is FALSE. */
- _auto_download = gconf_client_get_bool(gconf_client,
- GCONF_KEY_AUTO_DOWNLOAD, NULL);
+ sprintf(buffer, "#%02x%02x%02x",
+ _color_route.red >> 8,
+ _color_route.green >> 8,
+ _color_route.blue >> 8);
+ gconf_client_set_string(gconf_client,
+ GCONF_KEY_COLOR_ROUTE, buffer, NULL);
- /* Get Center Ratio - Default is 3. */
- _center_ratio = gconf_client_get_int(gconf_client,
- GCONF_KEY_CENTER_SENSITIVITY, NULL);
- if(!_center_ratio)
- _center_ratio = 7;
+ sprintf(buffer, "#%02x%02x%02x",
+ _color_route_way.red >> 8,
+ _color_route_way.green >> 8,
+ _color_route_way.blue >> 8);
+ gconf_client_set_string(gconf_client,
+ GCONF_KEY_COLOR_ROUTE_WAY, buffer, NULL);
- /* Get Lead Ratio - Default is 5. */
- _lead_ratio = gconf_client_get_int(gconf_client,
- GCONF_KEY_LEAD_AMOUNT, NULL);
- if(!_lead_ratio)
- _lead_ratio = 5;
+ sprintf(buffer, "#%02x%02x%02x",
+ _color_route_nextway.red >> 8,
+ _color_route_nextway.green >> 8,
+ _color_route_nextway.blue >> 8);
+ gconf_client_set_string(gconf_client,
+ GCONF_KEY_COLOR_ROUTE_NEXTWAY, buffer, NULL);
- /* Get Draw Line Width- Default is 5. */
- _draw_line_width = gconf_client_get_int(gconf_client,
- GCONF_KEY_DRAW_LINE_WIDTH, NULL);
- if(!_draw_line_width)
- _draw_line_width = 5;
+ sprintf(buffer, "#%02x%02x%02x",
+ _color_poi.red >> 8,
+ _color_poi.green >> 8,
+ _color_poi.blue >> 8);
+ gconf_client_set_string(gconf_client,
+ GCONF_KEY_COLOR_POI, buffer, NULL);
- /* Get Announce Advance Notice - Default is 30. */
- value = gconf_client_get(gconf_client, GCONF_KEY_ANNOUNCE_NOTICE, NULL);
- if(value)
- {
- _announce_notice_ratio = gconf_value_get_int(value);
- gconf_value_free(value);
- }
+ /* Save POI database. */
+ if(_poi_db)
+ gconf_client_set_string(gconf_client,
+ GCONF_KEY_POI_DB, _poi_db, NULL);
else
- _announce_notice_ratio = 8;
+ gconf_client_unset(gconf_client, GCONF_KEY_POI_DB, NULL);
- /* Get Enable Voice flag. Default is TRUE. */
- value = gconf_client_get(gconf_client, GCONF_KEY_ENABLE_VOICE, NULL);
- if(value)
- {
- _enable_voice = gconf_value_get_bool(value);
- gconf_value_free(value);
- }
- else
- _enable_voice = TRUE;
+ /* Save Show POI below zoom. */
+ gconf_client_set_int(gconf_client,
+ GCONF_KEY_POI_ZOOM, _poi_zoom, NULL);
- /* Get Voice Speed - Default is 1.0. */
- value = gconf_client_get(gconf_client, GCONF_KEY_VOICE_SPEED, NULL);
- if(value)
- {
- _voice_speed = gconf_value_get_float(value);
- gconf_value_free(value);
- }
- else
- _voice_speed = 1.0;
+ g_object_unref(gconf_client);
- /* Get Voice Speed - Default is 0. */
- value = gconf_client_get(gconf_client, GCONF_KEY_VOICE_PITCH, NULL);
- if(value)
+ /* Save route. */
{
- _voice_pitch = gconf_value_get_int(value);
- gconf_value_free(value);
+ GnomeVFSHandle *handle;
+ gchar *route_file;
+ route_file = gnome_vfs_uri_make_full_from_relative(
+ _config_dir_uri, CONFIG_FILE_ROUTE);
+ if(GNOME_VFS_OK == gnome_vfs_create(&handle, route_file,
+ GNOME_VFS_OPEN_WRITE, FALSE, 0600))
+ {
+ write_route_gpx(handle);
+ gnome_vfs_close(handle);
+ }
+ g_free(route_file);
}
- else
- _voice_pitch = 3;
-
- /* Get Always Keep On flag. Default is FALSE. */
- _always_keep_on = gconf_client_get_bool(gconf_client,
- GCONF_KEY_ALWAYS_KEEP_ON, NULL);
- /* Get Units. Default is UNITS_KM. */
+ /* Save track. */
{
- gchar *units_str = gconf_client_get_string(gconf_client,
- GCONF_KEY_UNITS, NULL);
- guint i;
- for(i = UNITS_ENUM_COUNT - 1; i > 0; i--)
- if(!strcmp(units_str, UNITS_TEXT[i]))
- break;
- _units = i;
+ GnomeVFSHandle *handle;
+ gchar *track_file;
+ track_file = gnome_vfs_uri_make_full_from_relative(
+ _config_dir_uri, CONFIG_FILE_TRACK);
+ if(GNOME_VFS_OK == gnome_vfs_create(&handle, track_file,
+ GNOME_VFS_OPEN_WRITE, FALSE, 0600))
+ {
+ write_track_gpx(handle);
+ gnome_vfs_close(handle);
+ }
+ g_free(track_file);
}
- /* Get Escape Key. Default is ESCAPE_KEY_TOGGLE_TRACKS. */
- {
- gchar *escape_key_str = gconf_client_get_string(gconf_client,
- GCONF_KEY_ESCAPE_KEY, NULL);
- guint i;
- for(i = ESCAPE_KEY_ENUM_COUNT - 1; i > 0; i--)
- if(!strcmp(escape_key_str, ESCAPE_KEY_TEXT[i]))
- break;
- _escape_key = i;
- }
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
- /* Get last saved latitude. Default is 0. */
- _pos_lat = gconf_client_get_float(gconf_client, GCONF_KEY_LAT, NULL);
+static void
+force_min_visible_bars(HildonControlbar *control_bar, gint num_bars)
+{
+ GValue val;
+ memset(&val, 0, sizeof(val));
+ g_value_init(&val, G_TYPE_INT);
+ g_value_set_int(&val, num_bars);
+ g_object_set_property(G_OBJECT(control_bar), "minimum-visible-bars", &val);
+}
- /* Get last saved longitude. Default is somewhere in Midwest. */
- value = gconf_client_get(gconf_client, GCONF_KEY_LON, NULL);
- _pos_lon = gconf_client_get_float(gconf_client, GCONF_KEY_LON, NULL);
- /* Get last center point. */
- {
- gfloat center_lat, center_lon;
+typedef struct _ScanInfo ScanInfo;
+struct _ScanInfo {
+ GtkWidget *settings_dialog;
+ GtkWidget *txt_rcvr_mac;
+ GtkWidget *scan_dialog;
+ GtkWidget *banner;
+ GtkListStore *store;
+ guint sid;
+};
- /* Get last saved latitude. Default is last saved latitude. */
- value = gconf_client_get(gconf_client, GCONF_KEY_CENTER_LAT, NULL);
- if(value)
- {
- center_lat = gconf_value_get_float(value);
- gconf_value_free(value);
- }
- else
- center_lat = _pos_lat;
+static gboolean
+scan_bluetooth_idle(ScanInfo *scan_info)
+{
+ gint devid, num_rsp;
+ GtkTreeIter iter;
+ inquiry_info *ii = NULL;
- /* Get last saved longitude. Default is last saved longitude. */
- value = gconf_client_get(gconf_client, GCONF_KEY_CENTER_LON, NULL);
- if(value)
- {
- center_lon = gconf_value_get_float(value);
- gconf_value_free(value);
- }
- else
- center_lon = _pos_lon;
+ devid = hci_get_route(NULL);
- latlon2unit(center_lat, center_lon, _center.unitx, _center.unity);
- }
+ ii = (inquiry_info*)malloc(255 * sizeof(inquiry_info));
+ num_rsp = hci_inquiry(devid, 4, 255, NULL, &ii, IREQ_CACHE_FLUSH);
- /* Load the repositories. */
+ if(num_rsp < 0)
{
- GSList *list, *curr;
- guint curr_repo_index = gconf_client_get_int(gconf_client,
- GCONF_KEY_CURRREPO, NULL);
- list = gconf_client_get_list(gconf_client,
- GCONF_KEY_REPOSITORIES, GCONF_VALUE_STRING, NULL);
-
- for(curr = list; curr != NULL; curr = curr->next)
- {
- /* Parse each part of a repo, delimited by newline characters:
- * 1. url
- * 2. cache_dir
- * 3. dl_zoom_steps
- * 4. view_zoom_steps
- */
- gchar *str = curr->data;
- RepoData *rd = g_new(RepoData, 1);
- rd->name = g_strdup(strsep(&str, "\n"));
- rd->url = g_strdup(strsep(&str, "\n"));
- rd->cache_dir = g_strdup(strsep(&str, "\n"));
- if(!(rd->dl_zoom_steps = atoi(strsep(&str, "\n"))))
- rd->dl_zoom_steps = 2;
- if(!(rd->view_zoom_steps = atoi(strsep(&str, "\n"))))
- rd->view_zoom_steps = 1;
-
- _repo_list = g_list_append(_repo_list, rd);
- if(!curr_repo_index--)
- _curr_repo = rd;
- g_free(curr->data);
- }
- g_slist_free(list);
+ gtk_widget_destroy(scan_info->banner);
+ gtk_widget_hide(scan_info->scan_dialog);
+ popup_error(scan_info->settings_dialog,
+ _("An error occurred while scanning."));
}
-
- if(_repo_list == NULL)
+ else if(num_rsp == 0)
{
- /* We have no repositories - create a default one. */
- _curr_repo = g_new(RepoData, 1);
-
- /* Many fields can be retrieved from the "old" gconf keys. */
-
- /* Get Map Cache Dir. Default is ~/MyDocs/.documents/Maps. */
- _curr_repo->cache_dir = gconf_client_get_string(gconf_client,
- GCONF_KEY_MAP_DIR_NAME, NULL);
-
- if(!_curr_repo->cache_dir)
- _curr_repo->cache_dir = gnome_vfs_expand_initial_tilde(
- "~/MyDocs/.documents/Maps");
-
- /* Get Map Download URI Format. Default is "". */
- _curr_repo->url = gconf_client_get_string(gconf_client,
- GCONF_KEY_MAP_URI_FORMAT, NULL);
- if(!_curr_repo->url)
- _curr_repo->url = g_strdup("");
+ gtk_widget_destroy(scan_info->banner);
+ gtk_widget_hide(scan_info->scan_dialog);
+ popup_error(scan_info->settings_dialog,
+ _("No bluetooth devices found."));
+ }
+ else
+ {
+ guint i;
+ gint sock = hci_open_dev(devid);
+ for(i = 0; i < num_rsp; i++)
+ {
+ gchar addr[19] = { 0 };
+ gchar name[256] = { 0 };
- /* Get Map Download Zoom Steps. Default is 2. */
- _curr_repo->dl_zoom_steps = gconf_client_get_int(gconf_client,
- GCONF_KEY_MAP_ZOOM_STEPS, NULL);
- if(!_curr_repo->dl_zoom_steps)
- _curr_repo->dl_zoom_steps = 2;
+ ba2str(&ii[i].bdaddr, addr);
+ memset(name, 0, sizeof(name));
+ if(hci_read_remote_name(sock, &ii[i].bdaddr, sizeof(name), name, 0))
+ strcpy(name, _("Unknown"));
- /* Other fields are brand new. */
- _curr_repo->name = g_strdup("Default");
- _curr_repo->view_zoom_steps = 1;
- _repo_list = g_list_append(_repo_list, _curr_repo);
+ gtk_list_store_append(scan_info->store, &iter);
+ gtk_list_store_set(scan_info->store, &iter,
+ 0, g_strdup(addr),
+ 1, g_strdup(name),
+ -1);
+ }
+ close(sock);
+ gtk_widget_destroy(scan_info->banner);
}
+ free(ii);
+ scan_info->sid = 0;
+ return FALSE;
+}
- /* Get last Zoom Level. Default is 16. */
- value = gconf_client_get(gconf_client, GCONF_KEY_ZOOM, NULL);
- if(value)
- {
- _zoom = gconf_value_get_int(value) / _curr_repo->view_zoom_steps
- * _curr_repo->view_zoom_steps;
- gconf_value_free(value);
- }
- else
- _zoom = 16 / _curr_repo->view_zoom_steps
- * _curr_repo->view_zoom_steps;
- BOUND(_zoom, 0, MAX_ZOOM - 1);
- _world_size_tiles = unit2tile(WORLD_SIZE_UNITS);
+/**
+ * Scan for all bluetooth devices. This method can take a few seconds,
+ * during which the UI will freeze.
+ */
+static gboolean
+scan_bluetooth(GtkWidget *widget, ScanInfo *scan_info)
+{
+ /* Do an hci_inquiry for our boy. */
+ GtkWidget *dialog;
+ GtkWidget *lst_devices;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer;
+ printf("%s()\n", __PRETTY_FUNCTION__);
- /* Speed and Heading are always initialized as 0. */
- _speed = 0.f;
- _heading = 0.f;
+ dialog = gtk_dialog_new_with_buttons(_("Select Bluetooth Device"),
+ GTK_WINDOW(scan_info->settings_dialog), GTK_DIALOG_MODAL,
+ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+ NULL);
- /* Get Route Directory. Default is NULL. */
- _route_dir_uri = gconf_client_get_string(gconf_client,
- GCONF_KEY_ROUTEDIR, NULL);
+ scan_info->scan_dialog = dialog;
- /* Get Last Track File. Default is NULL. */
- _track_file_uri = gconf_client_get_string(gconf_client,
- GCONF_KEY_TRACKFILE, NULL);
+ scan_info->banner = hildon_banner_show_animation(dialog, NULL,
+ _("Scanning Bluetooth Devices"));
- /* Get Auto-Center Mode. Default is CENTER_LEAD. */
- value = gconf_client_get(gconf_client, GCONF_KEY_AUTOCENTER_MODE, NULL);
- if(value)
- {
- _center_mode = gconf_value_get_int(value);
- gconf_value_free(value);
- }
- else
- _center_mode = CENTER_LEAD;
+ scan_info->store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
- /* Get Show Tracks flag. Default is TRUE. */
- value = gconf_client_get(gconf_client, GCONF_KEY_SHOWTRACKS, NULL);
- if(value)
- {
- _show_tracks |= (gconf_value_get_bool(value) ? TRACKS_MASK : 0);
- gconf_value_free(value);
- }
- else
- _show_tracks |= TRACKS_MASK;
+ scan_info->sid = g_idle_add((GSourceFunc)scan_bluetooth_idle, scan_info);
- /* Get Show Routes flag. Default is TRUE. */
- value = gconf_client_get(gconf_client, GCONF_KEY_SHOWROUTES, NULL);
- if(value)
- {
- _show_tracks |= (gconf_value_get_bool(value) ? ROUTES_MASK : 0);
- gconf_value_free(value);
- }
- else
- _show_tracks |= ROUTES_MASK;
+ gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 300);
- /* Get Show Velocity Vector flag. Default is TRUE. */
- value = gconf_client_get(gconf_client, GCONF_KEY_SHOWVELVEC, NULL);
- if(value)
- {
- _show_velvec = gconf_value_get_bool(value);
- gconf_value_free(value);
- }
- else
- _show_velvec = TRUE;
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+ lst_devices = gtk_tree_view_new_with_model(
+ GTK_TREE_MODEL(scan_info->store)), TRUE, TRUE, 0);
- /* Get Enable GPS flag. Default is TRUE. */
- value = gconf_client_get(gconf_client, GCONF_KEY_ENABLE_GPS, NULL);
- if(value)
- {
- _enable_gps = gconf_value_get_bool(value);
- gconf_value_free(value);
- }
- else
- _enable_gps = TRUE;
+ g_object_unref(G_OBJECT(scan_info->store));
- /* Initialize _conn_state based on _enable_gps. */
- _conn_state = (_enable_gps ? RCVR_DOWN : RCVR_OFF);
+ gtk_tree_selection_set_mode(
+ gtk_tree_view_get_selection(GTK_TREE_VIEW(lst_devices)),
+ GTK_SELECTION_SINGLE);
+ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(lst_devices), TRUE);
- /* Load the route locations. */
+ renderer = gtk_cell_renderer_text_new();
+ column = gtk_tree_view_column_new_with_attributes(
+ _("MAC"), renderer, "text", 0);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(lst_devices), column);
+
+ renderer = gtk_cell_renderer_text_new();
+ column = gtk_tree_view_column_new_with_attributes(
+ _("Description"), renderer, "text", 1);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(lst_devices), column);
+
+ gtk_widget_show_all(dialog);
+
+ while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
{
- GSList *curr;
- _loc_list = gconf_client_get_list(gconf_client,
- GCONF_KEY_ROUTE_LOCATIONS, GCONF_VALUE_STRING, NULL);
- _loc_model = gtk_list_store_new(1, G_TYPE_STRING);
- for(curr = _loc_list; curr != NULL; curr = curr->next)
+ GtkTreeIter iter;
+ if(gtk_tree_selection_get_selected(
+ gtk_tree_view_get_selection(GTK_TREE_VIEW(lst_devices)),
+ NULL, &iter))
{
- GtkTreeIter iter;
- gtk_list_store_insert_with_values(_loc_model, &iter, INT_MAX,
- 0, curr->data, -1);
+ gchar *mac;
+ gtk_tree_model_get(GTK_TREE_MODEL(scan_info->store),
+ &iter, 0, &mac, -1);
+ gtk_entry_set_text(GTK_ENTRY(scan_info->txt_rcvr_mac), mac);
+ break;
}
+ else
+ popup_error(dialog,
+ _("Please select a bluetooth device from the list."));
}
- /* Get POI Database. Default is in ~/MyDocs/.documents/Maps */
- _poi_db = gconf_client_get_string(gconf_client,
- GCONF_KEY_POI_DB, NULL);
- if(_poi_db == NULL)
- _poi_db = gnome_vfs_make_uri_full_from_relative(
- _curr_repo->cache_dir, "poi.db");
- db_connect();
+ if(scan_info->sid)
+ g_source_remove(scan_info->sid);
+ gtk_widget_destroy(dialog);
- _poi_zoom = gconf_client_get_int(gconf_client,
- GCONF_KEY_POI_ZOOM, NULL);
- if(!_poi_zoom)
- _poi_zoom = 6;
+ vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+ return TRUE;
+}
+typedef struct _BrowseInfo BrowseInfo;
+struct _BrowseInfo {
+ GtkWidget *dialog;
+ GtkWidget *txt;
+};
- /* Get GPS Info flag. Default is FALSE. */
- value = gconf_client_get(gconf_client, GCONF_KEY_GPS_INFO, NULL);
- if(value)
- {
- _gps_info = gconf_value_get_bool(value);
- gconf_value_free(value);
- }
- else
- _gps_info = FALSE;
+static gboolean
+settings_dialog_browse_forfile(GtkWidget *widget, BrowseInfo *browse_info)
+{
+ GtkWidget *dialog;
+ printf("%s()\n", __PRETTY_FUNCTION__);
- /* Initialize colors. */
- str = gconf_client_get_string(gconf_client,
- GCONF_KEY_COLOR_MARK, NULL);
- if(!str || !gdk_color_parse(str, &_color_mark))
- _color_mark = DEFAULT_COLOR_MARK;
+ dialog = GTK_WIDGET(
+ hildon_file_chooser_dialog_new(GTK_WINDOW(browse_info->dialog),
+ GTK_FILE_CHOOSER_ACTION_OPEN));
- str = gconf_client_get_string(gconf_client,
- GCONF_KEY_COLOR_MARK_VELOCITY, NULL);
- if(!str || !gdk_color_parse(str, &_color_mark_velocity))
- _color_mark_velocity = DEFAULT_COLOR_MARK_VELOCITY;
+ gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(dialog), TRUE);
+ gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),
+ gtk_entry_get_text(GTK_ENTRY(browse_info->txt)));
- str = gconf_client_get_string(gconf_client,
- GCONF_KEY_COLOR_MARK_OLD, NULL);
- if(!str || !gdk_color_parse(str, &_color_mark_old))
- _color_mark_old = DEFAULT_COLOR_MARK_OLD;
+ if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(dialog)))
+ {
+ gchar *filename = gtk_file_chooser_get_filename(
+ GTK_FILE_CHOOSER(dialog));
+ gtk_entry_set_text(GTK_ENTRY(browse_info->txt), filename);
+ g_free(filename);
+ }
- str = gconf_client_get_string(gconf_client,
- GCONF_KEY_COLOR_TRACK, NULL);
- if(!str || !gdk_color_parse(str, &_color_track))
- _color_track = DEFAULT_COLOR_TRACK;
+ gtk_widget_destroy(dialog);
- str = gconf_client_get_string(gconf_client,
- GCONF_KEY_COLOR_TRACK_BREAK, NULL);
- if(!str || !gdk_color_parse(str, &_color_track_break))
- _color_track_break = DEFAULT_COLOR_TRACK_BREAK;
+ vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+ return TRUE;
+}
- str = gconf_client_get_string(gconf_client,
- GCONF_KEY_COLOR_ROUTE, NULL);
- if(!str || !gdk_color_parse(str, &_color_route))
- _color_route = DEFAULT_COLOR_ROUTE;
- str = gconf_client_get_string(gconf_client,
- GCONF_KEY_COLOR_ROUTE_WAY, NULL);
- if(!str || !gdk_color_parse(str, &_color_route_way))
- _color_route_way = DEFAULT_COLOR_ROUTE_WAY;
+typedef struct _ColorsDialogInfo ColorsDialogInfo;
+struct _ColorsDialogInfo {
+ GtkWidget *col_mark;
+ GtkWidget *col_mark_velocity;
+ GtkWidget *col_mark_old;
+ GtkWidget *col_track;
+ GtkWidget *col_track_break;
+ GtkWidget *col_route;
+ GtkWidget *col_route_way;
+ GtkWidget *col_route_nextway;
+ GtkWidget *col_poi;
+};
- str = gconf_client_get_string(gconf_client,
- GCONF_KEY_COLOR_ROUTE_NEXTWAY, NULL);
- if(!str || !gdk_color_parse(str, &_color_route_nextway))
- _color_route_nextway = DEFAULT_COLOR_ROUTE_NEXTWAY;
+static gboolean
+settings_dialog_colors_reset(GtkWidget *widget, ColorsDialogInfo *cdi)
+{
+ hildon_color_button_set_color(
+ HILDON_COLOR_BUTTON(cdi->col_mark),
+ &DEFAULT_COLOR_MARK);
+ hildon_color_button_set_color(
+ HILDON_COLOR_BUTTON(cdi->col_mark_velocity),
+ &DEFAULT_COLOR_MARK_VELOCITY);
+ hildon_color_button_set_color(
+ HILDON_COLOR_BUTTON(cdi->col_mark_old),
+ &DEFAULT_COLOR_MARK_OLD);
+ hildon_color_button_set_color(
+ HILDON_COLOR_BUTTON(cdi->col_track),
+ &DEFAULT_COLOR_TRACK);
+ hildon_color_button_set_color(
+ HILDON_COLOR_BUTTON(cdi->col_track_break),
+ &DEFAULT_COLOR_TRACK_BREAK);
+ hildon_color_button_set_color(
+ HILDON_COLOR_BUTTON(cdi->col_route),
+ &DEFAULT_COLOR_ROUTE);
+ hildon_color_button_set_color(
+ HILDON_COLOR_BUTTON(cdi->col_route_way),
+ &DEFAULT_COLOR_ROUTE_WAY);
+ hildon_color_button_set_color(
+ HILDON_COLOR_BUTTON(cdi->col_route_nextway),
+ &DEFAULT_COLOR_ROUTE_NEXTWAY);
+ hildon_color_button_set_color(
+ HILDON_COLOR_BUTTON(cdi->col_poi),
+ &DEFAULT_COLOR_POI);
+ return TRUE;
+}
- str = gconf_client_get_string(gconf_client,
- GCONF_KEY_COLOR_POI, NULL);
- if(!str || !gdk_color_parse(str, &_color_poi))
- _color_poi = DEFAULT_COLOR_POI;
+static gboolean
+settings_dialog_colors(GtkWidget *widget, GtkWidget *parent)
+{
+ GtkWidget *dialog;
+ GtkWidget *table;
+ GtkWidget *label;
+ GtkWidget *btn_defaults;
+ ColorsDialogInfo cdi;
+ printf("%s()\n", __PRETTY_FUNCTION__);
+ dialog = gtk_dialog_new_with_buttons(_("Colors"),
+ GTK_WINDOW(parent), GTK_DIALOG_MODAL,
+ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+ NULL);
- g_object_unref(gconf_client);
+ gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
+ btn_defaults = gtk_button_new_with_label(_("Defaults")));
+ g_signal_connect(G_OBJECT(btn_defaults), "clicked",
+ G_CALLBACK(settings_dialog_colors_reset), &cdi);
- /* GPS data init */
- _gps.fix = 1;
- _gps.satinuse = 0;
- _gps.satinview = 0;
+ gtk_dialog_add_button(GTK_DIALOG(dialog),
+ GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+ table = gtk_table_new(4, 3, FALSE), TRUE, TRUE, 0);
-static void
-menu_maps_remove_repos()
-{
- GList *curr;
- printf("%s()\n", __PRETTY_FUNCTION__);
+ /* Mark. */
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_label_new(_("GPS Mark")),
+ 0, 1, 0, 1, GTK_FILL, 0, 2, 4);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table),
+ cdi.col_mark = hildon_color_button_new(),
+ 1, 2, 0, 1, 0, 0, 2, 4);
+ hildon_color_button_set_color(
+ HILDON_COLOR_BUTTON(cdi.col_mark), &_color_mark);
+ gtk_table_attach(GTK_TABLE(table),
+ cdi.col_mark_velocity = hildon_color_button_new(),
+ 2, 3, 0, 1, 0, 0, 2, 4);
+ hildon_color_button_set_color(
+ HILDON_COLOR_BUTTON(cdi.col_mark_velocity), &_color_mark_velocity);
+ gtk_table_attach(GTK_TABLE(table),
+ cdi.col_mark_old = hildon_color_button_new(),
+ 3, 4, 0, 1, 0, 0, 2, 4);
+ hildon_color_button_set_color(
+ HILDON_COLOR_BUTTON(cdi.col_mark_old), &_color_mark_old);
- /* Delete one menu item for each repo. */
- for(curr = _repo_list; curr; curr = curr->next)
- {
- gtk_widget_destroy(gtk_container_get_children(
- GTK_CONTAINER(_menu_maps_submenu))->data);
- }
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
+ /* Track. */
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_label_new(_("Track")),
+ 0, 1, 1, 2, GTK_FILL, 0, 2, 4);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table),
+ cdi.col_track = hildon_color_button_new(),
+ 1, 2, 1, 2, 0, 0, 2, 4);
+ hildon_color_button_set_color(
+ HILDON_COLOR_BUTTON(cdi.col_track), &_color_track);
+ gtk_table_attach(GTK_TABLE(table),
+ cdi.col_track_break = hildon_color_button_new(),
+ 2, 3, 1, 2, 0, 0, 2, 4);
+ hildon_color_button_set_color(
+ HILDON_COLOR_BUTTON(cdi.col_track_break), &_color_track_break);
-static void
-menu_maps_add_repos()
-{
- GList *curr;
- GtkWidget *last_repo = NULL;
- printf("%s()\n", __PRETTY_FUNCTION__);
+ /* Route. */
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_label_new(_("Route")),
+ 0, 1, 2, 3, GTK_FILL, 0, 2, 4);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table),
+ cdi.col_route = hildon_color_button_new(),
+ 1, 2, 2, 3, 0, 0, 2, 4);
+ hildon_color_button_set_color(
+ HILDON_COLOR_BUTTON(cdi.col_route), &_color_route);
+ gtk_table_attach(GTK_TABLE(table),
+ cdi.col_route_way = hildon_color_button_new(),
+ 2, 3, 2, 3, 0, 0, 2, 4);
+ hildon_color_button_set_color(
+ HILDON_COLOR_BUTTON(cdi.col_route_way), &_color_route_way);
+ gtk_table_attach(GTK_TABLE(table),
+ cdi.col_route_nextway = hildon_color_button_new(),
+ 3, 4, 2, 3, 0, 0, 2, 4);
+ hildon_color_button_set_color(
+ HILDON_COLOR_BUTTON(cdi.col_route_nextway), &_color_route_nextway);
- for(curr = g_list_last(_repo_list); curr; curr = curr->prev)
- {
- RepoData *rd = (RepoData*)curr->data;
- GtkWidget *menu_item;
- if(last_repo)
- gtk_menu_prepend(_menu_maps_submenu, menu_item
- = gtk_radio_menu_item_new_with_label_from_widget(
- GTK_RADIO_MENU_ITEM(last_repo), rd->name));
- else
- {
- gtk_menu_prepend(_menu_maps_submenu, menu_item
- = gtk_radio_menu_item_new_with_label(NULL, rd->name));
- last_repo = menu_item;
- }
- gtk_check_menu_item_set_active(
- GTK_CHECK_MENU_ITEM(menu_item),
- rd == _curr_repo);
- rd->menu_item = menu_item;
- }
+ /* POI. */
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_label_new(_("POI")),
+ 0, 1, 3, 4, GTK_FILL, 0, 2, 4);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table),
+ cdi.col_poi = hildon_color_button_new(),
+ 1, 2, 3, 4, 0, 0, 2, 4);
+ hildon_color_button_set_color(
+ HILDON_COLOR_BUTTON(cdi.col_poi), &_color_poi);
- /* Add signals (must be after entire menu is built). */
+ gtk_widget_show_all(dialog);
+
+ while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
{
- GList *currmi = gtk_container_get_children(
- GTK_CONTAINER(_menu_maps_submenu));
- for(curr = _repo_list; curr; curr = curr->next, currmi = currmi->next)
- {
- g_signal_connect(G_OBJECT(currmi->data), "activate",
- G_CALLBACK(menu_cb_maps_select), curr->data);
- }
+ GdkColor *color;
+
+ color = hildon_color_button_get_color(
+ HILDON_COLOR_BUTTON(cdi.col_mark));
+ _color_mark = *color;
+
+ color = hildon_color_button_get_color(
+ HILDON_COLOR_BUTTON(cdi.col_mark_velocity));
+ _color_mark_velocity = *color;
+
+ color = hildon_color_button_get_color(
+ HILDON_COLOR_BUTTON(cdi.col_mark_old));
+ _color_mark_old = *color;
+
+ color = hildon_color_button_get_color(
+ HILDON_COLOR_BUTTON(cdi.col_track));
+ _color_track = *color;
+
+ color = hildon_color_button_get_color(
+ HILDON_COLOR_BUTTON(cdi.col_track_break));
+ _color_track_break = *color;
+
+ color = hildon_color_button_get_color(
+ HILDON_COLOR_BUTTON(cdi.col_route));
+ _color_route = *color;
+
+ color = hildon_color_button_get_color(
+ HILDON_COLOR_BUTTON(cdi.col_route_way));
+ _color_route_way = *color;
+
+ color = hildon_color_button_get_color(
+ HILDON_COLOR_BUTTON(cdi.col_route_nextway));
+ _color_route_nextway = *color;
+
+ color = hildon_color_button_get_color(
+ HILDON_COLOR_BUTTON(cdi.col_poi));
+ _color_poi = *color;
+
+ update_gcs();
+ break;
}
- gtk_widget_show_all(_menu_maps_submenu);
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+ gtk_widget_destroy(dialog);
+
+ vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+ return TRUE;
}
/**
- * Create the menu items needed for the drop down menu.
+ * Bring up the Settings dialog. Return TRUE if and only if the recever
+ * information has changed (MAC or channel).
*/
-static void
-menu_init()
+static gboolean
+settings_dialog()
{
- /* Create needed handles. */
- GtkMenu *menu;
- GtkWidget *submenu;
- GtkWidget *menu_item;
- printf("%s()\n", __PRETTY_FUNCTION__);
+ GtkWidget *dialog;
+ GtkWidget *notebook;
+ GtkWidget *table;
+ GtkWidget *hbox;
+ GtkWidget *hbox2;
+ GtkWidget *label;
+ GtkWidget *txt_rcvr_mac;
+ GtkWidget *num_rcvr_chan;
+ GtkWidget *num_center_ratio;
+ GtkWidget *num_lead_ratio;
+ GtkWidget *num_announce_notice;
+ GtkWidget *chk_enable_voice;
+ GtkWidget *num_voice_speed;
+ GtkWidget *num_voice_pitch;
+ GtkWidget *num_draw_line_width;
+ GtkWidget *chk_always_keep_on;
+ GtkWidget *cmb_units;
+ GtkWidget *cmb_escape_key;
+ GtkWidget *btn_scan;
+ GtkWidget *btn_colors;
- /* Get the menu of our view. */
- menu = GTK_MENU(gtk_menu_new());
+ GtkWidget *txt_poi_db;
+ GtkWidget *btn_browsepoi;
+ GtkWidget *num_poi_zoom;
- /* Create the menu items. */
+ BrowseInfo browse_info = {0, 0};
+ ScanInfo scan_info = {0};
+ gboolean rcvr_changed = FALSE;
+ guint i;
+ printf("%s()\n", __PRETTY_FUNCTION__);
- /* The "Routes" submenu. */
- gtk_menu_append(menu, menu_item
- = gtk_menu_item_new_with_label(_("Route")));
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
- submenu = gtk_menu_new());
- gtk_menu_append(submenu, _menu_route_open_item
- = gtk_menu_item_new_with_label(_("Open...")));
- gtk_menu_append(submenu, _menu_route_download_item
- = gtk_menu_item_new_with_label(_("Download...")));
- gtk_menu_append(submenu, _menu_route_save_item
- = gtk_menu_item_new_with_label(_("Save...")));
- gtk_menu_append(submenu, _menu_route_reset_item
- = gtk_menu_item_new_with_label(_("Reset")));
- gtk_menu_append(submenu, _menu_route_clear_item
- = gtk_menu_item_new_with_label(_("Clear")));
+ dialog = gtk_dialog_new_with_buttons(_("Maemo Mapper Settings"),
+ GTK_WINDOW(_window), GTK_DIALOG_MODAL,
+ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+ NULL);
- /* The "Track" submenu. */
- gtk_menu_append(menu, menu_item
- = gtk_menu_item_new_with_label(_("Track")));
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
- submenu = gtk_menu_new());
- gtk_menu_append(submenu, _menu_track_open_item
- = gtk_menu_item_new_with_label(_("Open...")));
- gtk_menu_append(submenu, _menu_track_save_item
- = gtk_menu_item_new_with_label(_("Save...")));
- gtk_menu_append(submenu, _menu_track_mark_way_item
- = gtk_menu_item_new_with_label(_("Insert Breakpoint")));
- gtk_menu_append(submenu, _menu_track_clear_item
- = gtk_menu_item_new_with_label(_("Clear")));
+ gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
+ btn_colors = gtk_button_new_with_label(_("Colors...")));
- gtk_menu_append(menu, menu_item
- = gtk_menu_item_new_with_label(_("Maps")));
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
- _menu_maps_submenu = gtk_menu_new());
- gtk_menu_append(_menu_maps_submenu, gtk_separator_menu_item_new());
- gtk_menu_append(_menu_maps_submenu, _menu_maps_mapman_item
- = gtk_menu_item_new_with_label(_("Manage Maps...")));
- gtk_menu_append(_menu_maps_submenu, _menu_maps_repoman_item
- = gtk_menu_item_new_with_label(_("Manage Repositories...")));
- gtk_menu_append(_menu_maps_submenu, _menu_auto_download_item
- = gtk_check_menu_item_new_with_label(_("Auto-Download")));
- gtk_check_menu_item_set_active(
- GTK_CHECK_MENU_ITEM(_menu_auto_download_item), _auto_download);
- menu_maps_add_repos(_curr_repo);
+ gtk_dialog_add_button(GTK_DIALOG(dialog),
+ GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
- gtk_menu_append(menu, gtk_separator_menu_item_new());
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+ notebook = gtk_notebook_new(), TRUE, TRUE, 0);
- gtk_menu_append(menu, menu_item
- = gtk_menu_item_new_with_label(_("View")));
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
- submenu = gtk_menu_new());
- gtk_menu_append(submenu, _menu_fullscreen_item
- = gtk_check_menu_item_new_with_label(_("Full Screen")));
- gtk_check_menu_item_set_active(
- GTK_CHECK_MENU_ITEM(_menu_fullscreen_item), _fullscreen);
- gtk_menu_append(submenu, _menu_show_routes_item
- = gtk_check_menu_item_new_with_label(_("Route")));
- gtk_check_menu_item_set_active(
- GTK_CHECK_MENU_ITEM(_menu_show_routes_item),
- _show_tracks & ROUTES_MASK);
- gtk_menu_append(submenu, _menu_show_tracks_item
- = gtk_check_menu_item_new_with_label(_("Track")));
- gtk_check_menu_item_set_active(
- GTK_CHECK_MENU_ITEM(_menu_show_tracks_item),
- _show_tracks & TRACKS_MASK);
- gtk_menu_append(submenu, _menu_show_velvec_item
- = gtk_check_menu_item_new_with_label(_("Velocity Vector")));
- gtk_check_menu_item_set_active(
- GTK_CHECK_MENU_ITEM(_menu_show_velvec_item), _show_velvec);
- gtk_menu_append(submenu, _menu_poi_item
- = gtk_menu_item_new_with_label(_("POI Categories...")));
- gtk_widget_set_sensitive(_menu_poi_item, _dbconn);
+ /* Receiver page. */
+ gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
+ table = gtk_table_new(2, 3, FALSE),
+ label = gtk_label_new(_("GPS")));
+ /* Receiver MAC Address. */
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_label_new(_("MAC")),
+ 0, 1, 0, 1, GTK_FILL, 0, 2, 4);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table),
+ hbox = gtk_hbox_new(FALSE, 4),
+ 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+ gtk_box_pack_start(GTK_BOX(hbox),
+ txt_rcvr_mac = gtk_entry_new(),
+ TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox),
+ btn_scan = gtk_button_new_with_label(_("Scan...")),
+ FALSE, FALSE, 0);
- gtk_menu_append(menu, menu_item
- = gtk_menu_item_new_with_label(_("Auto-Center")));
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
- submenu = gtk_menu_new());
- gtk_menu_append(submenu, _menu_ac_latlon_item
- = gtk_radio_menu_item_new_with_label(NULL, _("Lat/Lon")));
- gtk_check_menu_item_set_active(
- GTK_CHECK_MENU_ITEM(_menu_ac_latlon_item),
- _center_mode == CENTER_LATLON);
- gtk_menu_append(submenu, _menu_ac_lead_item
- = gtk_radio_menu_item_new_with_label_from_widget(
- GTK_RADIO_MENU_ITEM(_menu_ac_latlon_item), _("Lead")));
- gtk_check_menu_item_set_active(
- GTK_CHECK_MENU_ITEM(_menu_ac_lead_item),
- _center_mode == CENTER_LEAD);
- gtk_menu_append(submenu, _menu_ac_none_item
- = gtk_radio_menu_item_new_with_label_from_widget(
- GTK_RADIO_MENU_ITEM(_menu_ac_latlon_item), _("None")));
- gtk_check_menu_item_set_active(
- GTK_CHECK_MENU_ITEM(_menu_ac_none_item),
- _center_mode < 0);
+ /* Receiver Channel. */
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_label_new(_("Channel")),
+ 0, 1, 1, 2, GTK_FILL, 0, 2, 4);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
+ 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+ gtk_container_add(GTK_CONTAINER(label),
+ num_rcvr_chan = hildon_number_editor_new(0, 255));
- gtk_menu_append(menu, menu_item
- = gtk_menu_item_new_with_label(_("GPS")));
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
- submenu = gtk_menu_new());
- gtk_menu_append(submenu, _menu_enable_gps_item
- = gtk_check_menu_item_new_with_label(_("Enable GPS")));
- gtk_check_menu_item_set_active(
- GTK_CHECK_MENU_ITEM(_menu_enable_gps_item), _enable_gps);
- gtk_menu_append(submenu, _menu_gps_show_info_item
- = gtk_check_menu_item_new_with_label(_("Show Information")));
- gtk_check_menu_item_set_active(
- GTK_CHECK_MENU_ITEM(_menu_gps_show_info_item), _gps_info);
- gtk_menu_append(submenu, _menu_gps_details_item
- = gtk_menu_item_new_with_label(_("Details...")));
- gtk_widget_set_sensitive(GTK_WIDGET(_menu_gps_details_item), _enable_gps);
- gtk_menu_append(submenu, _menu_gps_reset_item
- = gtk_menu_item_new_with_label(_("Reset Bluetooth")));
- gtk_widget_set_sensitive(GTK_WIDGET(_menu_gps_reset_item), _enable_gps);
+ /* Note!. */
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_label_new(
+ _("Note: \"Channel\" refers to the device side!")),
+ 0, 2, 2, 3, GTK_FILL, 0, 2, 4);
+ gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
+ gtk_misc_set_alignment(GTK_MISC(label), 0.5f, 0.5f);
- gtk_menu_append(menu, gtk_separator_menu_item_new());
- gtk_menu_append(menu, _menu_settings_item
- = gtk_menu_item_new_with_label(_("Settings...")));
+ /* Auto-Center page. */
+ gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
+ table = gtk_table_new(2, 2, FALSE),
+ label = gtk_label_new(_("Auto-Center")));
- gtk_menu_append(menu, gtk_separator_menu_item_new());
+ /* Auto-Center Sensitivity. */
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_label_new(_("Sensitivity")),
+ 0, 1, 0, 1, GTK_FILL, 0, 2, 4);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
+ 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+ gtk_container_add(GTK_CONTAINER(label),
+ num_center_ratio = hildon_controlbar_new());
+ hildon_controlbar_set_range(HILDON_CONTROLBAR(num_center_ratio), 1, 10);
+ force_min_visible_bars(HILDON_CONTROLBAR(num_center_ratio), 1);
- gtk_menu_append(menu, _menu_help_item
- = gtk_menu_item_new_with_label(_("Help")));
+ /* Lead Amount. */
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_label_new(_("Lead Amount")),
+ 0, 1, 1, 2, GTK_FILL, 0, 2, 4);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
+ 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+ gtk_container_add(GTK_CONTAINER(label),
+ num_lead_ratio = hildon_controlbar_new());
+ hildon_controlbar_set_range(HILDON_CONTROLBAR(num_lead_ratio), 1, 10);
+ force_min_visible_bars(HILDON_CONTROLBAR(num_lead_ratio), 1);
- gtk_menu_append(menu, _menu_close_item
- = gtk_menu_item_new_with_label(_("Close")));
+ /* Announcement. */
+ gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
+ table = gtk_table_new(2, 3, FALSE),
+ label = gtk_label_new(_("Announce")));
- /* We need to show menu items. */
- gtk_widget_show_all(GTK_WIDGET(menu));
+ /* Announcement Advance Notice. */
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_label_new(_("Advance Notice")),
+ 0, 1, 0, 1, GTK_FILL, 0, 2, 4);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table),
+ num_announce_notice = hildon_controlbar_new(),
+ 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+ hildon_controlbar_set_range(HILDON_CONTROLBAR(num_announce_notice), 1, 20);
+ force_min_visible_bars(HILDON_CONTROLBAR(num_announce_notice), 1);
- hildon_window_set_menu(HILDON_WINDOW(_window), menu);
+ /* Enable Voice. */
+ gtk_table_attach(GTK_TABLE(table),
+ chk_enable_voice = gtk_check_button_new_with_label(
+ _("Enable Voice Synthesis (requires flite)")),
+ 0, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chk_enable_voice),
+ _enable_voice);
- /* Connect the signals. */
- g_signal_connect(G_OBJECT(_menu_route_open_item), "activate",
- G_CALLBACK(menu_cb_route_open), NULL);
- g_signal_connect(G_OBJECT(_menu_route_download_item), "activate",
- G_CALLBACK(menu_cb_route_download), NULL);
- g_signal_connect(G_OBJECT(_menu_route_save_item), "activate",
- G_CALLBACK(menu_cb_route_save), NULL);
- g_signal_connect(G_OBJECT(_menu_route_reset_item), "activate",
- G_CALLBACK(menu_cb_route_reset), NULL);
- g_signal_connect(G_OBJECT(_menu_route_clear_item), "activate",
- G_CALLBACK(menu_cb_route_clear), NULL);
- g_signal_connect(G_OBJECT(_menu_track_open_item), "activate",
- G_CALLBACK(menu_cb_track_open), NULL);
- g_signal_connect(G_OBJECT(_menu_track_save_item), "activate",
- G_CALLBACK(menu_cb_track_save), NULL);
- g_signal_connect(G_OBJECT(_menu_track_mark_way_item), "activate",
- G_CALLBACK(menu_cb_track_mark_way), NULL);
- g_signal_connect(G_OBJECT(_menu_track_clear_item), "activate",
- G_CALLBACK(menu_cb_track_clear), NULL);
- g_signal_connect(G_OBJECT(_menu_show_tracks_item), "toggled",
- G_CALLBACK(menu_cb_show_tracks), NULL);
- g_signal_connect(G_OBJECT(_menu_show_routes_item), "toggled",
- G_CALLBACK(menu_cb_show_routes), NULL);
- g_signal_connect(G_OBJECT(_menu_show_velvec_item), "toggled",
- G_CALLBACK(menu_cb_show_velvec), NULL);
- g_signal_connect(G_OBJECT(_menu_poi_item), "activate",
- G_CALLBACK(menu_cb_category), NULL);
+ /* Voice Speed and Pitch. */
+ gtk_table_attach(GTK_TABLE(table),
+ hbox = gtk_hbox_new(FALSE, 12),
+ 0, 2, 2, 3, 0, 0, 2, 6);
+ gtk_box_pack_start(GTK_BOX(hbox),
+ hbox2 = gtk_hbox_new(FALSE, 4),
+ TRUE, TRUE, 4);
+ gtk_box_pack_start(GTK_BOX(hbox2),
+ label = gtk_label_new(_("Speed")),
+ TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox2),
+ num_voice_speed = hildon_controlbar_new(),
+ TRUE, TRUE, 0);
+ hildon_controlbar_set_range(HILDON_CONTROLBAR(num_voice_speed), 1, 10);
+ force_min_visible_bars(HILDON_CONTROLBAR(num_voice_speed), 1);
- g_signal_connect(G_OBJECT(_menu_maps_repoman_item), "activate",
- G_CALLBACK(menu_cb_maps_repoman), NULL);
- g_signal_connect(G_OBJECT(_menu_maps_mapman_item), "activate",
- G_CALLBACK(menu_cb_mapman), NULL);
- g_signal_connect(G_OBJECT(_menu_ac_latlon_item), "toggled",
- G_CALLBACK(menu_cb_ac_latlon), NULL);
- g_signal_connect(G_OBJECT(_menu_ac_lead_item), "toggled",
- G_CALLBACK(menu_cb_ac_lead), NULL);
- g_signal_connect(G_OBJECT(_menu_ac_none_item), "toggled",
- G_CALLBACK(menu_cb_ac_none), NULL);
- g_signal_connect(G_OBJECT(_menu_fullscreen_item), "toggled",
- G_CALLBACK(menu_cb_fullscreen), NULL);
- g_signal_connect(G_OBJECT(_menu_enable_gps_item), "toggled",
- G_CALLBACK(menu_cb_enable_gps), NULL);
- g_signal_connect(G_OBJECT(_menu_gps_show_info_item), "toggled",
- G_CALLBACK(menu_cb_gps_show_info), NULL);
- g_signal_connect(G_OBJECT(_menu_gps_details_item), "activate",
- G_CALLBACK(menu_cb_gps_details), NULL);
- g_signal_connect(G_OBJECT(_menu_gps_reset_item), "activate",
- G_CALLBACK(menu_cb_gps_reset), NULL);
- g_signal_connect(G_OBJECT(_menu_auto_download_item), "toggled",
- G_CALLBACK(menu_cb_auto_download), NULL);
- g_signal_connect(G_OBJECT(_menu_settings_item), "activate",
- G_CALLBACK(menu_cb_settings), NULL);
- g_signal_connect(G_OBJECT(_menu_help_item), "activate",
- G_CALLBACK(menu_cb_help), NULL);
- g_signal_connect(G_OBJECT(_menu_close_item), "activate",
- G_CALLBACK(gtk_main_quit), NULL);
+ gtk_box_pack_start(GTK_BOX(hbox),
+ hbox2 = gtk_hbox_new(FALSE, 4),
+ TRUE, TRUE, 4);
+ gtk_box_pack_start(GTK_BOX(hbox2),
+ label = gtk_label_new(_("Pitch")),
+ TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox2),
+ num_voice_pitch = hildon_controlbar_new(),
+ TRUE, TRUE, 0);
+ hildon_controlbar_set_range(HILDON_CONTROLBAR(num_voice_pitch), -2, 8);
+ force_min_visible_bars(HILDON_CONTROLBAR(num_voice_pitch), 1);
- /* Setup the context menu. */
- menu = GTK_MENU(gtk_menu_new());
+ /* Misc. page. */
+ gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
+ table = gtk_table_new(2, 3, FALSE),
+ label = gtk_label_new(_("Misc.")));
- /* Setup the map context menu. */
- gtk_menu_append(menu, menu_item
- = gtk_menu_item_new_with_label(_("Location")));
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
- submenu = gtk_menu_new());
+ /* Line Width. */
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_label_new(_("Line Width")),
+ 0, 1, 0, 1, GTK_FILL, 0, 2, 4);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table),
+ num_draw_line_width = hildon_controlbar_new(),
+ 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+ hildon_controlbar_set_range(HILDON_CONTROLBAR(num_draw_line_width), 1, 20);
+ force_min_visible_bars(HILDON_CONTROLBAR(num_draw_line_width), 1);
- /* Setup the map context menu. */
- gtk_menu_append(submenu, _cmenu_loc_show_latlon_item
- = gtk_menu_item_new_with_label(_("Show Lat/Lon")));
- gtk_menu_append(submenu, _cmenu_loc_clip_latlon_item
- = gtk_menu_item_new_with_label(_("Copy Lat/Lon to Clipboard")));
- gtk_menu_append(submenu, gtk_separator_menu_item_new());
- gtk_menu_append(submenu, _cmenu_loc_route_to_item
- = gtk_menu_item_new_with_label(_("Download Route to...")));
- gtk_menu_append(submenu, _cmenu_loc_distance_to_item
- = gtk_menu_item_new_with_label(_("Show Distance to")));
- gtk_menu_append(submenu, gtk_separator_menu_item_new());
- gtk_menu_append(submenu, _cmenu_add_poi
- = gtk_menu_item_new_with_label(_("Add POI")));
- gtk_widget_set_sensitive(_cmenu_add_poi, _dbconn);
- gtk_menu_append(submenu, _cmenu_edit_poi
- = gtk_menu_item_new_with_label(_("Edit POI")));
- gtk_widget_set_sensitive(_cmenu_edit_poi, _dbconn);
+ /* Keep Display On Only When Fullscreen. */
+ gtk_table_attach(GTK_TABLE(table),
+ chk_always_keep_on = gtk_check_button_new_with_label(
+ _("Keep Display On Only in Fullscreen Mode")),
+ 0, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
- /* Setup the waypoint context menu. */
- gtk_menu_append(menu, menu_item
- = gtk_menu_item_new_with_label(_("Waypoint")));
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
- submenu = gtk_menu_new());
+ /* Units. */
+ gtk_table_attach(GTK_TABLE(table),
+ hbox = gtk_hbox_new(FALSE, 4),
+ 0, 2, 2, 3, GTK_FILL, 0, 2, 4);
+ gtk_box_pack_start(GTK_BOX(hbox),
+ label = gtk_label_new(_("Units")),
+ FALSE, FALSE, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+ gtk_box_pack_start(GTK_BOX(hbox),
+ label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
+ TRUE, TRUE, 0);
+ gtk_container_add(GTK_CONTAINER(label),
+ cmb_units = gtk_combo_box_new_text());
+ for(i = 0; i < UNITS_ENUM_COUNT; i++)
+ gtk_combo_box_append_text(GTK_COMBO_BOX(cmb_units), UNITS_TEXT[i]);
- gtk_menu_append(submenu, _cmenu_way_show_latlon_item
- = gtk_menu_item_new_with_label(_("Show Lat/Lon")));
- gtk_menu_append(submenu, _cmenu_way_show_desc_item
- = gtk_menu_item_new_with_label(_("Show Description")));
- gtk_menu_append(submenu, _cmenu_way_clip_latlon_item
- = gtk_menu_item_new_with_label(_("Copy Lat/Lon to Clipboard")));
- gtk_menu_append(submenu, _cmenu_way_clip_desc_item
- = gtk_menu_item_new_with_label(_("Copy Description to Clipboard")));
- gtk_menu_append(submenu, gtk_separator_menu_item_new());
- gtk_menu_append(submenu, _cmenu_way_route_to_item
- = gtk_menu_item_new_with_label(_("Download Route to...")));
- gtk_menu_append(submenu, _cmenu_way_distance_to_item
- = gtk_menu_item_new_with_label(_("Show Distance to")));
- gtk_menu_append(submenu, _cmenu_way_delete_item
- = gtk_menu_item_new_with_label(_("Delete")));
+ /* Escape Key. */
+ gtk_box_pack_start(GTK_BOX(hbox),
+ label = gtk_label_new(_("Escape Key")),
+ FALSE, FALSE, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+ gtk_box_pack_start(GTK_BOX(hbox),
+ label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
+ TRUE, TRUE, 0);
+ gtk_container_add(GTK_CONTAINER(label),
+ cmb_escape_key = gtk_combo_box_new_text());
+ for(i = 0; i < ESCAPE_KEY_ENUM_COUNT; i++)
+ gtk_combo_box_append_text(GTK_COMBO_BOX(cmb_escape_key),
+ ESCAPE_KEY_TEXT[i]);
- /* Connect signals for context menu. */
- g_signal_connect(G_OBJECT(_cmenu_loc_show_latlon_item), "activate",
- G_CALLBACK(cmenu_cb_loc_show_latlon), NULL);
- g_signal_connect(G_OBJECT(_cmenu_loc_clip_latlon_item), "activate",
- G_CALLBACK(cmenu_cb_loc_clip_latlon), NULL);
- g_signal_connect(G_OBJECT(_cmenu_loc_route_to_item), "activate",
- G_CALLBACK(cmenu_cb_loc_route_to), NULL);
- g_signal_connect(G_OBJECT(_cmenu_loc_distance_to_item), "activate",
- G_CALLBACK(cmenu_cb_loc_distance_to), NULL);
- g_signal_connect(G_OBJECT(_cmenu_add_poi), "activate",
- G_CALLBACK(cmenu_cb_add_poi), NULL);
- g_signal_connect(G_OBJECT(_cmenu_edit_poi), "activate",
- G_CALLBACK(cmenu_cb_edit_poi), NULL);
- g_signal_connect(G_OBJECT(_cmenu_way_show_latlon_item), "activate",
- G_CALLBACK(cmenu_cb_way_show_latlon), NULL);
- g_signal_connect(G_OBJECT(_cmenu_way_show_desc_item), "activate",
- G_CALLBACK(cmenu_cb_way_show_desc), NULL);
- g_signal_connect(G_OBJECT(_cmenu_way_clip_latlon_item), "activate",
- G_CALLBACK(cmenu_cb_way_clip_latlon), NULL);
- g_signal_connect(G_OBJECT(_cmenu_way_clip_desc_item), "activate",
- G_CALLBACK(cmenu_cb_way_clip_desc), NULL);
- g_signal_connect(G_OBJECT(_cmenu_way_route_to_item), "activate",
- G_CALLBACK(cmenu_cb_way_route_to), NULL);
- g_signal_connect(G_OBJECT(_cmenu_way_distance_to_item), "activate",
- G_CALLBACK(cmenu_cb_way_distance_to), NULL);
- g_signal_connect(G_OBJECT(_cmenu_way_delete_item), "activate",
- G_CALLBACK(cmenu_cb_way_delete), NULL);
+ /* POI page */
+ gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
+ table = gtk_table_new(2, 3, FALSE),
+ label = gtk_label_new(_("POI")));
- gtk_widget_show_all(GTK_WIDGET(menu));
+ /* POI database. */
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_label_new(_("POI database")),
+ 0, 1, 1, 2, GTK_FILL, 0, 2, 4);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table),
+ hbox = gtk_hbox_new(FALSE, 4),
+ 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+ gtk_box_pack_start(GTK_BOX(hbox),
+ txt_poi_db = gtk_entry_new(),
+ TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox),
+ btn_browsepoi = gtk_button_new_with_label(_("Browse...")),
+ FALSE, FALSE, 0);
- gtk_widget_tap_and_hold_setup(_map_widget, GTK_WIDGET(menu), NULL, 0);
+ /* Show POI below zoom. */
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_label_new(_("Show POI below zoom")),
+ 0, 1, 2, 3, GTK_FILL, 0, 2, 4);
+ gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table),
+ label = gtk_alignment_new(0.f, 0.5f, 0.f, 0.f),
+ 1, 2, 2, 3, GTK_EXPAND | GTK_FILL, 0, 2, 4);
+ gtk_container_add(GTK_CONTAINER(label),
+ num_poi_zoom = hildon_number_editor_new(0, MAX_ZOOM));
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
-/**
- * Call gtk_window_present() on Maemo Mapper. This also checks the
- * configuration and brings up the Settings dialog if the GPS Receiver is
- * not set up, the first time it is called.
- */
-static gboolean
-window_present()
-{
- static gint been_here = 0;
- printf("%s()\n", __PRETTY_FUNCTION__);
+ /* Connect signals. */
+ scan_info.settings_dialog = dialog;
+ scan_info.txt_rcvr_mac = txt_rcvr_mac;
+ g_signal_connect(G_OBJECT(btn_scan), "clicked",
+ G_CALLBACK(scan_bluetooth), &scan_info);
+ g_signal_connect(G_OBJECT(btn_colors), "clicked",
+ G_CALLBACK(settings_dialog_colors), dialog);
- if(!been_here++)
- {
- /* Set connection state first, to avoid going into this if twice. */
- if(_rcvr_mac || !_enable_gps || settings_dialog())
- {
- gtk_widget_show_all(_window);
- gps_show_info();
+ browse_info.dialog = dialog;
+ browse_info.txt = txt_poi_db;
+ g_signal_connect(G_OBJECT(btn_browsepoi), "clicked",
+ G_CALLBACK(settings_dialog_browse_forfile), &browse_info);
- /* Connect to receiver. */
- if(_enable_gps)
- rcvr_connect_now();
- }
- else
- gtk_main_quit();
- }
- gtk_window_present(GTK_WINDOW(_window));
-
- /* Re-enable any banners that might have been up. */
- {
- ConnState old_state = _conn_state;
- set_conn_state(RCVR_OFF);
- set_conn_state(old_state);
- }
+ /* Initialize fields. */
+ if(_rcvr_mac)
+ gtk_entry_set_text(GTK_ENTRY(txt_rcvr_mac), _rcvr_mac);
+ hildon_number_editor_set_value(HILDON_NUMBER_EDITOR(num_rcvr_chan),
+ _rcvr_addr.rc_channel);
+ if(_poi_db)
+ gtk_entry_set_text(GTK_ENTRY(txt_poi_db), _poi_db);
+ hildon_number_editor_set_value(HILDON_NUMBER_EDITOR(num_poi_zoom),
+ _poi_zoom);
+ hildon_controlbar_set_value(HILDON_CONTROLBAR(num_center_ratio),
+ _center_ratio);
+ hildon_controlbar_set_value(HILDON_CONTROLBAR(num_lead_ratio),
+ _lead_ratio);
+ hildon_controlbar_set_value(HILDON_CONTROLBAR(num_announce_notice),
+ _announce_notice_ratio);
+ hildon_controlbar_set_value(HILDON_CONTROLBAR(num_voice_speed),
+ (gint)(_voice_speed * 3 + 0.5));
+ hildon_controlbar_set_value(HILDON_CONTROLBAR(num_voice_pitch),
+ _voice_pitch);
+ hildon_controlbar_set_value(HILDON_CONTROLBAR(num_draw_line_width),
+ _draw_line_width);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chk_always_keep_on),
+ !_always_keep_on);
+ gtk_combo_box_set_active(GTK_COMBO_BOX(cmb_units), _units);
+ gtk_combo_box_set_active(GTK_COMBO_BOX(cmb_escape_key), _escape_key);
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
- return FALSE;
-}
+ gtk_widget_show_all(dialog);
-/**
- * Get the hash value of a ProgressUpdateInfo object. This is trivial, since
- * the hash is generated and stored when the object is created.
- */
-static guint
-download_hashfunc(ProgressUpdateInfo *pui)
-{
- vprintf("%s()\n", __PRETTY_FUNCTION__);
+ while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
+ {
+ /* Set _rcvr_mac if necessary. */
+ if(!*gtk_entry_get_text(GTK_ENTRY(txt_rcvr_mac)))
+ {
+ /* User specified no rcvr mac - set _rcvr_mac to NULL. */
+ if(_rcvr_mac)
+ {
+ g_free(_rcvr_mac);
+ _rcvr_mac = NULL;
+ rcvr_changed = TRUE;
+ gtk_widget_set_sensitive(
+ GTK_WIDGET(_menu_gps_details_item), FALSE);
+ }
+ if(_enable_gps)
+ {
+ gtk_check_menu_item_set_active(
+ GTK_CHECK_MENU_ITEM(_menu_enable_gps_item), FALSE);
+ popup_error(dialog, _("No GPS Receiver MAC Provided.\n"
+ "GPS Disabled."));
+ rcvr_changed = TRUE;
+ gtk_widget_set_sensitive(GTK_WIDGET(_menu_gps_details_item),
+ FALSE);
+ gtk_widget_set_sensitive(GTK_WIDGET(_menu_gps_reset_item),
+ FALSE);
+ }
+ }
+ else if(!_rcvr_mac || strcmp(_rcvr_mac,
+ gtk_entry_get_text(GTK_ENTRY(txt_rcvr_mac))))
+ {
+ /* User specified a new rcvr mac. */
+ g_free(_rcvr_mac);
+ _rcvr_mac = g_strdup(gtk_entry_get_text(GTK_ENTRY(txt_rcvr_mac)));
+ str2ba(_rcvr_mac, &_rcvr_addr.rc_bdaddr);
+ rcvr_changed = TRUE;
+ }
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
- return pui->hash;
-}
+ if(_rcvr_addr.rc_channel != hildon_number_editor_get_value(
+ HILDON_NUMBER_EDITOR(num_rcvr_chan)))
+ {
+ _rcvr_addr.rc_channel = hildon_number_editor_get_value(
+ HILDON_NUMBER_EDITOR(num_rcvr_chan));
+ rcvr_changed = TRUE;
+ }
-/**
- * Return whether or not two ProgressUpdateInfo objects are equal. They
- * are equal if they are downloading the same tile.
- */
-static gboolean
-download_equalfunc(
- ProgressUpdateInfo *pui1, ProgressUpdateInfo *pui2)
-{
- vprintf("%s()\n", __PRETTY_FUNCTION__);
+ _center_ratio = hildon_controlbar_get_value(
+ HILDON_CONTROLBAR(num_center_ratio));
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
- return pui1->tilex == pui2->tilex && pui1->tiley == pui2->tiley
- && pui1->zoom == pui2->zoom;
-}
+ _lead_ratio = hildon_controlbar_get_value(
+ HILDON_CONTROLBAR(num_lead_ratio));
-/**
- * Draw the current mark (representing the current GPS location) onto
- * _map_widget. This method does not queue the draw area.
- */
-static void
-map_draw_mark()
-{
- printf("%s()\n", __PRETTY_FUNCTION__);
+ _draw_line_width = hildon_controlbar_get_value(
+ HILDON_CONTROLBAR(num_draw_line_width));
- if(_enable_gps)
- {
- gdk_draw_arc(
- _map_widget->window,
- _conn_state == RCVR_FIXED ? _gc_mark : _gc_mark_old,
- FALSE, /* not filled. */
- _mark_x1 - _draw_line_width, _mark_y1 - _draw_line_width,
- 2 * _draw_line_width, 2 * _draw_line_width,
- 0, 360 * 64);
- gdk_draw_line(
- _map_widget->window,
- _conn_state == RCVR_FIXED
- ? (_show_velvec ? _gc_mark_velocity : _gc_mark)
- : _gc_mark_old,
- _mark_x1, _mark_y1, _mark_x2, _mark_y2);
- }
+ _always_keep_on = !gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON(chk_always_keep_on));
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
+ _units = gtk_combo_box_get_active(GTK_COMBO_BOX(cmb_units));
+ _escape_key = gtk_combo_box_get_active(GTK_COMBO_BOX(cmb_escape_key));
-/**
- * "Set" the mark, which translates the current GPS position into on-screen
- * units in preparation for drawing the mark with map_draw_mark().
- */
-static void map_set_mark()
-{
- printf("%s()\n", __PRETTY_FUNCTION__);
+ _announce_notice_ratio = hildon_controlbar_get_value(
+ HILDON_CONTROLBAR(num_announce_notice));
- _mark_x1 = unit2x(_pos.unitx);
- _mark_y1 = unit2y(_pos.unity);
- _mark_x2 = _mark_x1 + (_show_velvec ? _vel_offsetx : 0);
- _mark_y2 = _mark_y1 + (_show_velvec ? _vel_offsety : 0);
- _mark_minx = MIN(_mark_x1, _mark_x2) - (2 * _draw_line_width);
- _mark_miny = MIN(_mark_y1, _mark_y2) - (2 * _draw_line_width);
- _mark_width = abs(_mark_x1 - _mark_x2) + (4 * _draw_line_width);
- _mark_height = abs(_mark_y1 - _mark_y2) + (4 * _draw_line_width);
+ _voice_speed = hildon_controlbar_get_value(
+ HILDON_CONTROLBAR(num_voice_speed)) / 3.0;
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
+ _voice_pitch = hildon_controlbar_get_value(
+ HILDON_CONTROLBAR(num_voice_pitch));
-/**
- * Do an in-place scaling of a pixbuf's pixels at the given ratio from the
- * given source location. It would have been nice if gdk_pixbuf provided
- * this method, but I guess it's not general-purpose enough.
- */
-static void
-map_pixbuf_scale_inplace(guchar *pixels, guint ratio_p2,
- guint src_x, guint src_y)
-{
- guint dest_x = 0, dest_y = 0, dest_dim = TILE_SIZE_PIXELS;
- vprintf("%s(%d, %d, %d)\n", __PRETTY_FUNCTION__, ratio_p2, src_x, src_y);
+ _enable_voice = gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON(chk_enable_voice));
- /* Sweep through the entire dest area, copying as necessary, but
- * DO NOT OVERWRITE THE SOURCE AREA. We'll copy it afterward. */
- do {
- guint src_dim = dest_dim >> ratio_p2;
- guint src_endx = src_x - dest_x + src_dim;
- gint x, y;
- for(y = dest_dim - 1; y >= 0; y--)
+ if(_dbconn)
{
- guint src_offset_y, dest_offset_y;
- src_offset_y = (src_y + (y >> ratio_p2)) * TILE_PIXBUF_STRIDE;
- dest_offset_y = (dest_y + y) * TILE_PIXBUF_STRIDE;
- x = dest_dim - 1;
- if((unsigned)(dest_y + y - src_y) < src_dim
- && (unsigned)(dest_x + x - src_x) < src_dim)
- x -= src_dim;
- for(; x >= 0; x--)
- {
- guint src_offset, dest_offset;
- src_offset = src_offset_y + (src_x + (x >> ratio_p2)) * 3;
- dest_offset = dest_offset_y + (dest_x + x) * 3;
- pixels[dest_offset + 0] = pixels[src_offset + 0];
- pixels[dest_offset + 1] = pixels[src_offset + 1];
- pixels[dest_offset + 2] = pixels[src_offset + 2];
- if((unsigned)(dest_y + y - src_y) < src_dim && x == src_endx)
- x -= src_dim;
- }
+ sqlite_close(_db);
+ _dbconn = FALSE;
+ gtk_widget_set_sensitive(_cmenu_add_poi, FALSE);
+ gtk_widget_set_sensitive(_cmenu_edit_poi, FALSE);
+ gtk_widget_set_sensitive(_menu_poi_item, FALSE);
}
- /* Reuse src_dim and src_endx to store new src_x and src_y. */
- src_dim = src_x + ((src_x - dest_x) >> ratio_p2);
- src_endx = src_y + ((src_y - dest_y) >> ratio_p2);
- dest_x = src_x;
- dest_y = src_y;
- src_x = src_dim;
- src_y = src_endx;
- }
- while((dest_dim >>= ratio_p2) > 1);
+ g_free(_poi_db);
+ if(strlen(gtk_entry_get_text(GTK_ENTRY(txt_poi_db))))
+ {
+ _poi_db = g_strdup(gtk_entry_get_text(GTK_ENTRY(txt_poi_db)));
+ db_connect();
+ gtk_widget_set_sensitive(_cmenu_add_poi, _dbconn);
+ gtk_widget_set_sensitive(_cmenu_edit_poi, _dbconn);
+ gtk_widget_set_sensitive(_menu_poi_item, _dbconn);
+ }
+ else
+ _poi_db = NULL;
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
+ _poi_zoom = hildon_number_editor_get_value(
+ HILDON_NUMBER_EDITOR(num_poi_zoom));
-/**
- * Free a ProgressUpdateInfo data structure that was allocated during the
- * auto-map-download process.
- */
-static void
-progress_update_info_free(ProgressUpdateInfo *pui)
-{
- vprintf("%s()\n", __PRETTY_FUNCTION__);
+ update_gcs();
- gnome_vfs_uri_unref((GnomeVFSURI*)pui->src_list->data);
- g_list_free(pui->src_list);
- gnome_vfs_uri_unref((GnomeVFSURI*)pui->dest_list->data);
- g_list_free(pui->dest_list);
- g_free(pui);
+ config_save();
+ break;
+ }
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+ gtk_widget_hide(dialog); /* Destroying causes a crash (!?!?!??!) */
+
+ vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, rcvr_changed);
+ return rcvr_changed;
}
/**
- * Given the xyz coordinates of our map coordinate system, write the qrst
- * quadtree coordinates to buffer.
+ * Initialize all configuration from GCONF. This should not be called more
+ * than once during execution.
*/
static void
-map_convert_coords_to_quadtree_string(int x, int y, int zoomlevel,gchar *buffer)
+config_init()
{
- static const gchar *const quadrant = "qrts";
- gchar *ptr = buffer;
- int n;
- *ptr++ = 't';
- for(n = 16 - zoomlevel; n >= 0; n--)
+ GConfValue *value;
+ GConfClient *gconf_client = gconf_client_get_default();
+ gchar *str;
+ printf("%s()\n", __PRETTY_FUNCTION__);
+
+ if(!gconf_client)
{
- int xbit = (x >> n) & 1;
- int ybit = (y >> n) & 1;
- *ptr++ = quadrant[xbit + 2 * ybit];
+ popup_error(_window, _("Failed to initialize GConf. Quitting."));
+ exit(1);
}
- *ptr++ = '\0';
-}
-/**
- * Construct the URL that we should fetch, based on the current URI format.
- * This method works differently depending on if a "%s" string is present in
- * the URI format, since that would indicate a quadtree-based map coordinate
- * system.
- */
-static void
-map_construct_url(gchar *buffer, guint tilex, guint tiley, guint zoom)
-{
- if(strstr(_curr_repo->url, "%s"))
+ /* Initialize _config_dir. */
{
- /* This is a satellite-map URI. */
- gchar location[MAX_ZOOM + 2];
- map_convert_coords_to_quadtree_string(tilex, tiley, zoom, location);
- sprintf(buffer, _curr_repo->url, location);
+ gchar *config_dir;
+ config_dir = gnome_vfs_expand_initial_tilde(CONFIG_DIR_NAME);
+ _config_dir_uri = gnome_vfs_make_uri_from_input(config_dir);
+ gnome_vfs_make_directory(_config_dir_uri, 0700);
+ g_free(config_dir);
}
- else
- /* This is a street-map URI. */
- sprintf(buffer, _curr_repo->url, tilex, tiley, zoom);
-}
+ /* Retrieve route. */
+ {
+ gchar *route_file;
+ gchar *bytes;
+ gint size;
-/**
- * Initiate a download of the given xyz coordinates using the given buffer
- * as the URL. If the map already exists on disk, or if we are already
- * downloading the map, then this method does nothing.
- */
-static gboolean
-map_initiate_download(guint tilex, guint tiley, guint zoom, gint retries)
-{
- gchar buffer[1024];
- GnomeVFSURI *src, *dest;
- GList *src_list, *dest_list;
- gint priority;
- ProgressUpdateInfo *pui;
- vprintf("%s(%u, %u, %u, %d)\n", __PRETTY_FUNCTION__, tilex, tiley, zoom,
- retries);
+ route_file = gnome_vfs_uri_make_full_from_relative(
+ _config_dir_uri, CONFIG_FILE_ROUTE);
+ if(GNOME_VFS_OK == gnome_vfs_read_entire_file(
+ route_file, &size, &bytes))
+ parse_route_gpx(bytes, size, 0); /* 0 to replace route. */
+ g_free(route_file);
+ }
- pui = g_new(ProgressUpdateInfo, 1);
- pui->hash = tilex + (tiley << 12) + (zoom << 24);
- pui->tilex = tilex;
- pui->tiley = tiley;
- pui->zoom = zoom;
- if(g_hash_table_lookup(_downloads_hash, pui))
+ /* Retrieve track. */
{
- /* Already downloading - return FALSE. */
- g_free(pui);
- return FALSE;
+ gchar *track_file;
+ gchar *bytes;
+ gint size;
+
+ track_file = gnome_vfs_uri_make_full_from_relative(
+ _config_dir_uri, CONFIG_FILE_TRACK);
+ if(GNOME_VFS_OK == gnome_vfs_read_entire_file(
+ track_file, &size, &bytes))
+ parse_track_gpx(bytes, size, 0); /* 0 to replace track. */
+ g_free(track_file);
}
- sprintf(buffer, "%s/%u/%u/%u.jpg", _curr_repo->cache_dir,
- zoom, tilex, tiley);
- dest = gnome_vfs_uri_new(buffer);
- if(retries > 0 && gnome_vfs_uri_exists(dest))
+
+ /* Get Receiver MAC from GConf. Default is scanned via hci_inquiry. */
{
- /* Already downloaded and not overwriting - return FALSE. */
- gnome_vfs_uri_unref(dest);
- g_free(pui);
- return FALSE;
+ _rcvr_mac = gconf_client_get_string(
+ gconf_client, GCONF_KEY_RCVR_MAC, NULL);
+ if(_rcvr_mac)
+ str2ba(_rcvr_mac, &_rcvr_addr.rc_bdaddr);
}
- /* Priority is based on proximity to _center.unitx - lower number means
- * higher priority, so the further we are, the higher the number. */
- priority = GNOME_VFS_PRIORITY_MIN
- + unit2ptile(abs(tile2punit(tilex, zoom) - _center.unitx)
- + abs(tile2punit(tiley, zoom) - _center.unity));
- BOUND(priority, GNOME_VFS_PRIORITY_MIN, GNOME_VFS_PRIORITY_MAX);
+ /* Get Receiver Channel from GConf. Default is 1. */
+ _rcvr_addr.rc_family = AF_BLUETOOTH;
+ _rcvr_addr.rc_channel = gconf_client_get_int(gconf_client,
+ GCONF_KEY_RCVR_CHAN, NULL);
+ if(_rcvr_addr.rc_channel < 1)
+ _rcvr_addr.rc_channel = 1;
- map_construct_url(buffer, tilex, tiley, zoom);
- src = gnome_vfs_uri_new(buffer);
+ /* Get Auto-Download. Default is FALSE. */
+ _auto_download = gconf_client_get_bool(gconf_client,
+ GCONF_KEY_AUTO_DOWNLOAD, NULL);
- src_list = g_list_prepend(src_list = NULL, src);
- dest_list = g_list_prepend(dest_list = NULL, dest);
+ /* Get Center Ratio - Default is 3. */
+ _center_ratio = gconf_client_get_int(gconf_client,
+ GCONF_KEY_CENTER_SENSITIVITY, NULL);
+ if(!_center_ratio)
+ _center_ratio = 7;
- pui->src_list = src_list;
- pui->dest_list = dest_list;
- pui->retries_left = retries;
+ /* Get Lead Ratio - Default is 5. */
+ _lead_ratio = gconf_client_get_int(gconf_client,
+ GCONF_KEY_LEAD_AMOUNT, NULL);
+ if(!_lead_ratio)
+ _lead_ratio = 5;
- /* Initiate asynchronous download. */
- if(retries)
+ /* Get Draw Line Width- Default is 5. */
+ _draw_line_width = gconf_client_get_int(gconf_client,
+ GCONF_KEY_DRAW_LINE_WIDTH, NULL);
+ if(!_draw_line_width)
+ _draw_line_width = 5;
+
+ /* Get Announce Advance Notice - Default is 30. */
+ value = gconf_client_get(gconf_client, GCONF_KEY_ANNOUNCE_NOTICE, NULL);
+ if(value)
{
- /* This is a download; if retries < 0, then this is an overwrite */
- if(GNOME_VFS_OK != gnome_vfs_async_xfer(
- &pui->handle,
- src_list, dest_list,
- retries < 0 ? GNOME_VFS_XFER_DEFAULT
- : GNOME_VFS_XFER_USE_UNIQUE_NAMES,
- GNOME_VFS_XFER_ERROR_MODE_QUERY,
- retries < 0 ? GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE
- : GNOME_VFS_XFER_OVERWRITE_MODE_QUERY,
- priority,
- (GnomeVFSAsyncXferProgressCallback)map_download_cb_async,
- pui,
- (GnomeVFSXferProgressCallback)gtk_true,
- NULL))
- {
- progress_update_info_free(pui);
- return FALSE;
- }
+ _announce_notice_ratio = gconf_value_get_int(value);
+ gconf_value_free(value);
}
else
+ _announce_notice_ratio = 8;
+
+ /* Get Enable Voice flag. Default is TRUE. */
+ value = gconf_client_get(gconf_client, GCONF_KEY_ENABLE_VOICE, NULL);
+ if(value)
{
- /* This is a deletion. */
- if(GNOME_VFS_OK != gnome_vfs_async_xfer(
- &pui->handle,
- dest_list, NULL,
- GNOME_VFS_XFER_DELETE_ITEMS,
- GNOME_VFS_XFER_ERROR_MODE_QUERY,
- GNOME_VFS_XFER_OVERWRITE_MODE_QUERY,
- priority,
- (GnomeVFSAsyncXferProgressCallback)map_download_cb_async,
- pui,
- (GnomeVFSXferProgressCallback)gtk_true,
- NULL))
- {
- progress_update_info_free(pui);
- return FALSE;
- }
+ _enable_voice = gconf_value_get_bool(value);
+ gconf_value_free(value);
}
+ else
+ _enable_voice = TRUE;
- g_hash_table_insert(_downloads_hash, pui, pui);
- if(!_num_downloads++ && !_download_banner)
- _download_banner = hildon_banner_show_progress(
- _window, NULL, _("Downloading maps"));
+ /* Get Voice Speed - Default is 1.0. */
+ value = gconf_client_get(gconf_client, GCONF_KEY_VOICE_SPEED, NULL);
+ if(value)
+ {
+ _voice_speed = gconf_value_get_float(value);
+ gconf_value_free(value);
+ }
+ else
+ _voice_speed = 1.0;
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
- return TRUE;
-}
+ /* Get Voice Speed - Default is 0. */
+ value = gconf_client_get(gconf_client, GCONF_KEY_VOICE_PITCH, NULL);
+ if(value)
+ {
+ _voice_pitch = gconf_value_get_int(value);
+ gconf_value_free(value);
+ }
+ else
+ _voice_pitch = 3;
-static void
-map_render_poi()
-{
- guint unitx, unity;
- gfloat lat1, lat2, lon1, lon2, tmp;
- gchar slat1[10], slat2[10], slon1[10], slon2[10];
- gchar buffer[100];
- gchar **pszResult;
- gint nRow, nColumn, row, poix, poiy;
- GdkPixbuf *pixbuf = NULL;
- GError *error = NULL;
+ /* Get Always Keep On flag. Default is FALSE. */
+ _always_keep_on = gconf_client_get_bool(gconf_client,
+ GCONF_KEY_ALWAYS_KEEP_ON, NULL);
- if(_db && _poi_zoom > _zoom)
+ /* Get Units. Default is UNITS_KM. */
{
- unitx = x2unit(1);
- unity = y2unit(1);
- unit2latlon(unitx, unity, lat1, lon1);
- unitx = x2unit(BUF_WIDTH_PIXELS);
- unity = y2unit(BUF_HEIGHT_PIXELS);
- unit2latlon(unitx, unity, lat2, lon2);
- if(lat1 > lat2)
- {
- tmp = lat2;
- lat2 = lat1;
- lat1 = tmp;
- }
- if(lon1 > lon2)
+ gchar *units_str = gconf_client_get_string(gconf_client,
+ GCONF_KEY_UNITS, NULL);
+ guint i = 0;
+ if(units_str)
+ for(i = UNITS_ENUM_COUNT - 1; i > 0; i--)
+ if(!strcmp(units_str, UNITS_TEXT[i]))
+ break;
+ _units = i;
+ }
+
+ /* Get Escape Key. Default is ESCAPE_KEY_TOGGLE_TRACKS. */
+ {
+ gchar *escape_key_str = gconf_client_get_string(gconf_client,
+ GCONF_KEY_ESCAPE_KEY, NULL);
+ guint i = 0;
+ if(escape_key_str)
+ for(i = ESCAPE_KEY_ENUM_COUNT - 1; i > 0; i--)
+ if(!strcmp(escape_key_str, ESCAPE_KEY_TEXT[i]))
+ break;
+ _escape_key = i;
+ }
+
+ /* Get last saved latitude. Default is 0. */
+ _pos_lat = gconf_client_get_float(gconf_client, GCONF_KEY_LAT, NULL);
+
+ /* Get last saved longitude. Default is somewhere in Midwest. */
+ value = gconf_client_get(gconf_client, GCONF_KEY_LON, NULL);
+ _pos_lon = gconf_client_get_float(gconf_client, GCONF_KEY_LON, NULL);
+
+ /* Get last center point. */
+ {
+ gfloat center_lat, center_lon;
+
+ /* Get last saved latitude. Default is last saved latitude. */
+ value = gconf_client_get(gconf_client, GCONF_KEY_CENTER_LAT, NULL);
+ if(value)
{
- tmp = lon2;
- lon2 = lon1;
- lon1 = tmp;
+ center_lat = gconf_value_get_float(value);
+ gconf_value_free(value);
}
+ else
+ center_lat = _pos_lat;
+
+ /* Get last saved longitude. Default is last saved longitude. */
+ value = gconf_client_get(gconf_client, GCONF_KEY_CENTER_LON, NULL);
+ if(value)
+ {
+ center_lon = gconf_value_get_float(value);
+ gconf_value_free(value);
+ }
+ else
+ center_lon = _pos_lon;
+
+ latlon2unit(center_lat, center_lon, _center.unitx, _center.unity);
+ }
+
+ /* Load the repositories. */
+ {
+ GSList *list, *curr;
+ guint curr_repo_index = gconf_client_get_int(gconf_client,
+ GCONF_KEY_CURRREPO, NULL);
+ list = gconf_client_get_list(gconf_client,
+ GCONF_KEY_REPOSITORIES, GCONF_VALUE_STRING, NULL);
+
+ for(curr = list; curr != NULL; curr = curr->next)
+ {
+ /* Parse each part of a repo, delimited by newline characters:
+ * 1. url
+ * 2. cache_dir
+ * 3. dl_zoom_steps
+ * 4. view_zoom_steps
+ */
+ gchar *str = curr->data;
+ RepoData *rd = g_new(RepoData, 1);
+ rd->name = g_strdup(strsep(&str, "\n"));
+ rd->url = g_strdup(strsep(&str, "\n"));
+ rd->cache_dir = g_strdup(strsep(&str, "\n"));
+ if(!(rd->dl_zoom_steps = atoi(strsep(&str, "\n"))))
+ rd->dl_zoom_steps = 2;
+ if(!(rd->view_zoom_steps = atoi(strsep(&str, "\n"))))
+ rd->view_zoom_steps = 1;
+
+ _repo_list = g_list_append(_repo_list, rd);
+ if(!curr_repo_index--)
+ _curr_repo = rd;
+ g_free(curr->data);
+ }
+ g_slist_free(list);
+ }
+
+ if(_repo_list == NULL)
+ {
+ /* We have no repositories - create a default one. */
+ _curr_repo = g_new(RepoData, 1);
+
+ /* Many fields can be retrieved from the "old" gconf keys. */
+
+ /* Get Map Cache Dir. Default is ~/MyDocs/.documents/Maps. */
+ _curr_repo->cache_dir = gconf_client_get_string(gconf_client,
+ GCONF_KEY_MAP_DIR_NAME, NULL);
+
+ if(!_curr_repo->cache_dir)
+ _curr_repo->cache_dir = gnome_vfs_expand_initial_tilde(
+ "~/MyDocs/.documents/Maps");
+
+ /* Get Map Download URI Format. Default is "". */
+ _curr_repo->url = gconf_client_get_string(gconf_client,
+ GCONF_KEY_MAP_URI_FORMAT, NULL);
+ if(!_curr_repo->url)
+ _curr_repo->url = g_strdup("");
+
+ /* Get Map Download Zoom Steps. Default is 2. */
+ _curr_repo->dl_zoom_steps = gconf_client_get_int(gconf_client,
+ GCONF_KEY_MAP_ZOOM_STEPS, NULL);
+ if(!_curr_repo->dl_zoom_steps)
+ _curr_repo->dl_zoom_steps = 2;
+
+ /* Other fields are brand new. */
+ _curr_repo->name = g_strdup("Default");
+ _curr_repo->view_zoom_steps = 1;
+ _repo_list = g_list_append(_repo_list, _curr_repo);
+ }
+
+ /* Get last Zoom Level. Default is 16. */
+ value = gconf_client_get(gconf_client, GCONF_KEY_ZOOM, NULL);
+ if(value)
+ {
+ _zoom = gconf_value_get_int(value) / _curr_repo->view_zoom_steps
+ * _curr_repo->view_zoom_steps;
+ gconf_value_free(value);
+ }
+ else
+ _zoom = 16 / _curr_repo->view_zoom_steps
+ * _curr_repo->view_zoom_steps;
+ BOUND(_zoom, 0, MAX_ZOOM - 1);
+ _world_size_tiles = unit2tile(WORLD_SIZE_UNITS);
+
+ /* Speed and Heading are always initialized as 0. */
+ _speed = 0.f;
+ _heading = 0.f;
+
+ /* Get Route Directory. Default is NULL. */
+ _route_dir_uri = gconf_client_get_string(gconf_client,
+ GCONF_KEY_ROUTEDIR, NULL);
+
+ /* Get Last Track File. Default is NULL. */
+ _track_file_uri = gconf_client_get_string(gconf_client,
+ GCONF_KEY_TRACKFILE, NULL);
+
+ /* Get Auto-Center Mode. Default is CENTER_LEAD. */
+ value = gconf_client_get(gconf_client, GCONF_KEY_AUTOCENTER_MODE, NULL);
+ if(value)
+ {
+ _center_mode = gconf_value_get_int(value);
+ gconf_value_free(value);
+ }
+ else
+ _center_mode = CENTER_LEAD;
+
+ /* Get Show Tracks flag. Default is TRUE. */
+ value = gconf_client_get(gconf_client, GCONF_KEY_SHOWTRACKS, NULL);
+ if(value)
+ {
+ _show_tracks |= (gconf_value_get_bool(value) ? TRACKS_MASK : 0);
+ gconf_value_free(value);
+ }
+ else
+ _show_tracks |= TRACKS_MASK;
+
+ /* Get Show Routes flag. Default is TRUE. */
+ value = gconf_client_get(gconf_client, GCONF_KEY_SHOWROUTES, NULL);
+ if(value)
+ {
+ _show_tracks |= (gconf_value_get_bool(value) ? ROUTES_MASK : 0);
+ gconf_value_free(value);
+ }
+ else
+ _show_tracks |= ROUTES_MASK;
+
+ /* Get Show Velocity Vector flag. Default is TRUE. */
+ value = gconf_client_get(gconf_client, GCONF_KEY_SHOWVELVEC, NULL);
+ if(value)
+ {
+ _show_velvec = gconf_value_get_bool(value);
+ gconf_value_free(value);
+ }
+ else
+ _show_velvec = TRUE;
+
+ /* Get Enable GPS flag. Default is TRUE. */
+ value = gconf_client_get(gconf_client, GCONF_KEY_ENABLE_GPS, NULL);
+ if(value)
+ {
+ _enable_gps = gconf_value_get_bool(value);
+ gconf_value_free(value);
+ }
+ else
+ _enable_gps = TRUE;
+
+ /* Initialize _conn_state based on _enable_gps. */
+ _conn_state = (_enable_gps ? RCVR_DOWN : RCVR_OFF);
+
+ /* Load the route locations. */
+ {
+ GSList *curr;
+ _loc_list = gconf_client_get_list(gconf_client,
+ GCONF_KEY_ROUTE_LOCATIONS, GCONF_VALUE_STRING, NULL);
+ _loc_model = gtk_list_store_new(1, G_TYPE_STRING);
+ for(curr = _loc_list; curr != NULL; curr = curr->next)
+ {
+ GtkTreeIter iter;
+ gtk_list_store_insert_with_values(_loc_model, &iter, INT_MAX,
+ 0, curr->data, -1);
+ }
+ }
+
+ /* Get POI Database. Default is in ~/MyDocs/.documents/Maps */
+ _poi_db = gconf_client_get_string(gconf_client,
+ GCONF_KEY_POI_DB, NULL);
+ if(_poi_db == NULL)
+ _poi_db = gnome_vfs_make_uri_full_from_relative(
+ _curr_repo->cache_dir, "poi.db");
+ db_connect();
+
+ _poi_zoom = gconf_client_get_int(gconf_client,
+ GCONF_KEY_POI_ZOOM, NULL);
+ if(!_poi_zoom)
+ _poi_zoom = 6;
+
+
+ /* Get GPS Info flag. Default is FALSE. */
+ value = gconf_client_get(gconf_client, GCONF_KEY_GPS_INFO, NULL);
+ if(value)
+ {
+ _gps_info = gconf_value_get_bool(value);
+ gconf_value_free(value);
+ }
+ else
+ _gps_info = FALSE;
+
+ /* Get Route Download Radius. Default is 4. */
+ value = gconf_client_get(gconf_client, GCONF_KEY_ROUTE_DL_RADIUS, NULL);
+ if(value)
+ {
+ _route_dl_radius = gconf_value_get_int(value);
+ gconf_value_free(value);
+ }
+ else
+ _route_dl_radius = 4;
+
+ /* Initialize colors. */
+ str = gconf_client_get_string(gconf_client,
+ GCONF_KEY_COLOR_MARK, NULL);
+ if(!str || !gdk_color_parse(str, &_color_mark))
+ _color_mark = DEFAULT_COLOR_MARK;
+
+ str = gconf_client_get_string(gconf_client,
+ GCONF_KEY_COLOR_MARK_VELOCITY, NULL);
+ if(!str || !gdk_color_parse(str, &_color_mark_velocity))
+ _color_mark_velocity = DEFAULT_COLOR_MARK_VELOCITY;
+
+ str = gconf_client_get_string(gconf_client,
+ GCONF_KEY_COLOR_MARK_OLD, NULL);
+ if(!str || !gdk_color_parse(str, &_color_mark_old))
+ _color_mark_old = DEFAULT_COLOR_MARK_OLD;
+
+ str = gconf_client_get_string(gconf_client,
+ GCONF_KEY_COLOR_TRACK, NULL);
+ if(!str || !gdk_color_parse(str, &_color_track))
+ _color_track = DEFAULT_COLOR_TRACK;
+
+ str = gconf_client_get_string(gconf_client,
+ GCONF_KEY_COLOR_TRACK_BREAK, NULL);
+ if(!str || !gdk_color_parse(str, &_color_track_break))
+ _color_track_break = DEFAULT_COLOR_TRACK_BREAK;
+
+ str = gconf_client_get_string(gconf_client,
+ GCONF_KEY_COLOR_ROUTE, NULL);
+ if(!str || !gdk_color_parse(str, &_color_route))
+ _color_route = DEFAULT_COLOR_ROUTE;
+
+ str = gconf_client_get_string(gconf_client,
+ GCONF_KEY_COLOR_ROUTE_WAY, NULL);
+ if(!str || !gdk_color_parse(str, &_color_route_way))
+ _color_route_way = DEFAULT_COLOR_ROUTE_WAY;
+
+ str = gconf_client_get_string(gconf_client,
+ GCONF_KEY_COLOR_ROUTE_NEXTWAY, NULL);
+ if(!str || !gdk_color_parse(str, &_color_route_nextway))
+ _color_route_nextway = DEFAULT_COLOR_ROUTE_NEXTWAY;
+
+ str = gconf_client_get_string(gconf_client,
+ GCONF_KEY_COLOR_POI, NULL);
+ if(!str || !gdk_color_parse(str, &_color_poi))
+ _color_poi = DEFAULT_COLOR_POI;
+
+
+ g_object_unref(gconf_client);
+
+ /* GPS data init */
+ _gps.fix = 1;
+ _gps.satinuse = 0;
+ _gps.satinview = 0;
+
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+static void
+menu_maps_remove_repos()
+{
+ GList *curr;
+ printf("%s()\n", __PRETTY_FUNCTION__);
+
+ /* Delete one menu item for each repo. */
+ for(curr = _repo_list; curr; curr = curr->next)
+ {
+ gtk_widget_destroy(gtk_container_get_children(
+ GTK_CONTAINER(_menu_maps_submenu))->data);
+ }
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+static void
+menu_maps_add_repos()
+{
+ GList *curr;
+ GtkWidget *last_repo = NULL;
+ printf("%s()\n", __PRETTY_FUNCTION__);
+
+ for(curr = g_list_last(_repo_list); curr; curr = curr->prev)
+ {
+ RepoData *rd = (RepoData*)curr->data;
+ GtkWidget *menu_item;
+ if(last_repo)
+ gtk_menu_prepend(_menu_maps_submenu, menu_item
+ = gtk_radio_menu_item_new_with_label_from_widget(
+ GTK_RADIO_MENU_ITEM(last_repo), rd->name));
+ else
+ {
+ gtk_menu_prepend(_menu_maps_submenu, menu_item
+ = gtk_radio_menu_item_new_with_label(NULL, rd->name));
+ last_repo = menu_item;
+ }
+ gtk_check_menu_item_set_active(
+ GTK_CHECK_MENU_ITEM(menu_item),
+ rd == _curr_repo);
+ rd->menu_item = menu_item;
+ }
+
+ /* Add signals (must be after entire menu is built). */
+ {
+ GList *currmi = gtk_container_get_children(
+ GTK_CONTAINER(_menu_maps_submenu));
+ for(curr = _repo_list; curr; curr = curr->next, currmi = currmi->next)
+ {
+ g_signal_connect(G_OBJECT(currmi->data), "activate",
+ G_CALLBACK(menu_cb_maps_select), curr->data);
+ }
+ }
+
+ gtk_widget_show_all(_menu_maps_submenu);
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
+
+/**
+ * Create the menu items needed for the drop down menu.
+ */
+static void
+menu_init()
+{
+ /* Create needed handles. */
+ GtkMenu *menu;
+ GtkWidget *submenu;
+ GtkWidget *menu_item;
+ printf("%s()\n", __PRETTY_FUNCTION__);
+
+ /* Get the menu of our view. */
+ menu = GTK_MENU(gtk_menu_new());
+
+ /* Create the menu items. */
+
+ /* The "Routes" submenu. */
+ gtk_menu_append(menu, menu_item
+ = gtk_menu_item_new_with_label(_("Route")));
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
+ submenu = gtk_menu_new());
+ gtk_menu_append(submenu, _menu_route_open_item
+ = gtk_menu_item_new_with_label(_("Open...")));
+ gtk_menu_append(submenu, _menu_route_download_item
+ = gtk_menu_item_new_with_label(_("Download...")));
+ gtk_menu_append(submenu, _menu_route_save_item
+ = gtk_menu_item_new_with_label(_("Save...")));
+ gtk_menu_append(submenu, _menu_route_reset_item
+ = gtk_menu_item_new_with_label(_("Reset")));
+ gtk_menu_append(submenu, _menu_route_clear_item
+ = gtk_menu_item_new_with_label(_("Clear")));
- g_ascii_dtostr(slat1, sizeof(slat1), lat1);
- g_ascii_dtostr(slat2, sizeof(slat2), lat2);
- g_ascii_dtostr(slon1, sizeof(slon1), lon1);
- g_ascii_dtostr(slon2, sizeof(slon2), lon2);
+ /* The "Track" submenu. */
+ gtk_menu_append(menu, menu_item
+ = gtk_menu_item_new_with_label(_("Track")));
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
+ submenu = gtk_menu_new());
+ gtk_menu_append(submenu, _menu_track_open_item
+ = gtk_menu_item_new_with_label(_("Open...")));
+ gtk_menu_append(submenu, _menu_track_save_item
+ = gtk_menu_item_new_with_label(_("Save...")));
+ gtk_menu_append(submenu, _menu_track_mark_way_item
+ = gtk_menu_item_new_with_label(_("Insert Breakpoint")));
+ gtk_menu_append(submenu, _menu_track_clear_item
+ = gtk_menu_item_new_with_label(_("Clear")));
+
+ gtk_menu_append(menu, menu_item
+ = gtk_menu_item_new_with_label(_("Maps")));
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
+ _menu_maps_submenu = gtk_menu_new());
+ gtk_menu_append(_menu_maps_submenu, gtk_separator_menu_item_new());
+ gtk_menu_append(_menu_maps_submenu, _menu_maps_mapman_item
+ = gtk_menu_item_new_with_label(_("Manage Maps...")));
+ gtk_menu_append(_menu_maps_submenu, _menu_maps_repoman_item
+ = gtk_menu_item_new_with_label(_("Manage Repositories...")));
+ gtk_menu_append(_menu_maps_submenu, _menu_auto_download_item
+ = gtk_check_menu_item_new_with_label(_("Auto-Download")));
+ gtk_check_menu_item_set_active(
+ GTK_CHECK_MENU_ITEM(_menu_auto_download_item), _auto_download);
+ menu_maps_add_repos(_curr_repo);
+
+ gtk_menu_append(menu, gtk_separator_menu_item_new());
+
+ gtk_menu_append(menu, menu_item
+ = gtk_menu_item_new_with_label(_("View")));
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
+ submenu = gtk_menu_new());
+ gtk_menu_append(submenu, _menu_fullscreen_item
+ = gtk_check_menu_item_new_with_label(_("Full Screen")));
+ gtk_check_menu_item_set_active(
+ GTK_CHECK_MENU_ITEM(_menu_fullscreen_item), _fullscreen);
+ gtk_menu_append(submenu, _menu_show_routes_item
+ = gtk_check_menu_item_new_with_label(_("Route")));
+ gtk_check_menu_item_set_active(
+ GTK_CHECK_MENU_ITEM(_menu_show_routes_item),
+ _show_tracks & ROUTES_MASK);
+ gtk_menu_append(submenu, _menu_show_tracks_item
+ = gtk_check_menu_item_new_with_label(_("Track")));
+ gtk_check_menu_item_set_active(
+ GTK_CHECK_MENU_ITEM(_menu_show_tracks_item),
+ _show_tracks & TRACKS_MASK);
+ gtk_menu_append(submenu, _menu_show_velvec_item
+ = gtk_check_menu_item_new_with_label(_("Velocity Vector")));
+ gtk_check_menu_item_set_active(
+ GTK_CHECK_MENU_ITEM(_menu_show_velvec_item), _show_velvec);
+ gtk_menu_append(submenu, _menu_poi_item
+ = gtk_menu_item_new_with_label(_("POI Categories...")));
+ gtk_widget_set_sensitive(_menu_poi_item, _dbconn);
+
+
+ gtk_menu_append(menu, menu_item
+ = gtk_menu_item_new_with_label(_("Auto-Center")));
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
+ submenu = gtk_menu_new());
+ gtk_menu_append(submenu, _menu_ac_latlon_item
+ = gtk_radio_menu_item_new_with_label(NULL, _("Lat/Lon")));
+ gtk_check_menu_item_set_active(
+ GTK_CHECK_MENU_ITEM(_menu_ac_latlon_item),
+ _center_mode == CENTER_LATLON);
+ gtk_menu_append(submenu, _menu_ac_lead_item
+ = gtk_radio_menu_item_new_with_label_from_widget(
+ GTK_RADIO_MENU_ITEM(_menu_ac_latlon_item), _("Lead")));
+ gtk_check_menu_item_set_active(
+ GTK_CHECK_MENU_ITEM(_menu_ac_lead_item),
+ _center_mode == CENTER_LEAD);
+ gtk_menu_append(submenu, _menu_ac_none_item
+ = gtk_radio_menu_item_new_with_label_from_widget(
+ GTK_RADIO_MENU_ITEM(_menu_ac_latlon_item), _("None")));
+ gtk_check_menu_item_set_active(
+ GTK_CHECK_MENU_ITEM(_menu_ac_none_item),
+ _center_mode < 0);
+
+ gtk_menu_append(menu, menu_item
+ = gtk_menu_item_new_with_label(_("GPS")));
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
+ submenu = gtk_menu_new());
+ gtk_menu_append(submenu, _menu_enable_gps_item
+ = gtk_check_menu_item_new_with_label(_("Enable GPS")));
+ gtk_check_menu_item_set_active(
+ GTK_CHECK_MENU_ITEM(_menu_enable_gps_item), _enable_gps);
+ gtk_menu_append(submenu, _menu_gps_show_info_item
+ = gtk_check_menu_item_new_with_label(_("Show Information")));
+ gtk_check_menu_item_set_active(
+ GTK_CHECK_MENU_ITEM(_menu_gps_show_info_item), _gps_info);
+ gtk_menu_append(submenu, _menu_gps_details_item
+ = gtk_menu_item_new_with_label(_("Details...")));
+ gtk_widget_set_sensitive(GTK_WIDGET(_menu_gps_details_item), _enable_gps);
+ gtk_menu_append(submenu, _menu_gps_reset_item
+ = gtk_menu_item_new_with_label(_("Reset Bluetooth")));
+ gtk_widget_set_sensitive(GTK_WIDGET(_menu_gps_reset_item), _enable_gps);
+
+ gtk_menu_append(menu, gtk_separator_menu_item_new());
+
+ gtk_menu_append(menu, _menu_settings_item
+ = gtk_menu_item_new_with_label(_("Settings...")));
+
+ gtk_menu_append(menu, gtk_separator_menu_item_new());
+
+ gtk_menu_append(menu, _menu_help_item
+ = gtk_menu_item_new_with_label(_("Help")));
+
+ gtk_menu_append(menu, _menu_close_item
+ = gtk_menu_item_new_with_label(_("Close")));
+
+ /* We need to show menu items. */
+ gtk_widget_show_all(GTK_WIDGET(menu));
+
+ hildon_window_set_menu(HILDON_WINDOW(_window), menu);
+
+ /* Connect the signals. */
+ g_signal_connect(G_OBJECT(_menu_route_open_item), "activate",
+ G_CALLBACK(menu_cb_route_open), NULL);
+ g_signal_connect(G_OBJECT(_menu_route_download_item), "activate",
+ G_CALLBACK(menu_cb_route_download), NULL);
+ g_signal_connect(G_OBJECT(_menu_route_save_item), "activate",
+ G_CALLBACK(menu_cb_route_save), NULL);
+ g_signal_connect(G_OBJECT(_menu_route_reset_item), "activate",
+ G_CALLBACK(menu_cb_route_reset), NULL);
+ g_signal_connect(G_OBJECT(_menu_route_clear_item), "activate",
+ G_CALLBACK(menu_cb_route_clear), NULL);
+ g_signal_connect(G_OBJECT(_menu_track_open_item), "activate",
+ G_CALLBACK(menu_cb_track_open), NULL);
+ g_signal_connect(G_OBJECT(_menu_track_save_item), "activate",
+ G_CALLBACK(menu_cb_track_save), NULL);
+ g_signal_connect(G_OBJECT(_menu_track_mark_way_item), "activate",
+ G_CALLBACK(menu_cb_track_mark_way), NULL);
+ g_signal_connect(G_OBJECT(_menu_track_clear_item), "activate",
+ G_CALLBACK(menu_cb_track_clear), NULL);
+ g_signal_connect(G_OBJECT(_menu_show_tracks_item), "toggled",
+ G_CALLBACK(menu_cb_show_tracks), NULL);
+ g_signal_connect(G_OBJECT(_menu_show_routes_item), "toggled",
+ G_CALLBACK(menu_cb_show_routes), NULL);
+ g_signal_connect(G_OBJECT(_menu_show_velvec_item), "toggled",
+ G_CALLBACK(menu_cb_show_velvec), NULL);
+ g_signal_connect(G_OBJECT(_menu_poi_item), "activate",
+ G_CALLBACK(menu_cb_category), NULL);
+
+ g_signal_connect(G_OBJECT(_menu_maps_repoman_item), "activate",
+ G_CALLBACK(menu_cb_maps_repoman), NULL);
+ g_signal_connect(G_OBJECT(_menu_maps_mapman_item), "activate",
+ G_CALLBACK(menu_cb_mapman), NULL);
+ g_signal_connect(G_OBJECT(_menu_ac_latlon_item), "toggled",
+ G_CALLBACK(menu_cb_ac_latlon), NULL);
+ g_signal_connect(G_OBJECT(_menu_ac_lead_item), "toggled",
+ G_CALLBACK(menu_cb_ac_lead), NULL);
+ g_signal_connect(G_OBJECT(_menu_ac_none_item), "toggled",
+ G_CALLBACK(menu_cb_ac_none), NULL);
+ g_signal_connect(G_OBJECT(_menu_fullscreen_item), "toggled",
+ G_CALLBACK(menu_cb_fullscreen), NULL);
+ g_signal_connect(G_OBJECT(_menu_enable_gps_item), "toggled",
+ G_CALLBACK(menu_cb_enable_gps), NULL);
+ g_signal_connect(G_OBJECT(_menu_gps_show_info_item), "toggled",
+ G_CALLBACK(menu_cb_gps_show_info), NULL);
+ g_signal_connect(G_OBJECT(_menu_gps_details_item), "activate",
+ G_CALLBACK(menu_cb_gps_details), NULL);
+ g_signal_connect(G_OBJECT(_menu_gps_reset_item), "activate",
+ G_CALLBACK(menu_cb_gps_reset), NULL);
+ g_signal_connect(G_OBJECT(_menu_auto_download_item), "toggled",
+ G_CALLBACK(menu_cb_auto_download), NULL);
+ g_signal_connect(G_OBJECT(_menu_settings_item), "activate",
+ G_CALLBACK(menu_cb_settings), NULL);
+ g_signal_connect(G_OBJECT(_menu_help_item), "activate",
+ G_CALLBACK(menu_cb_help), NULL);
+ g_signal_connect(G_OBJECT(_menu_close_item), "activate",
+ G_CALLBACK(gtk_main_quit), NULL);
+
+ /* Setup the context menu. */
+ menu = GTK_MENU(gtk_menu_new());
+
+ /* Setup the map context menu. */
+ gtk_menu_append(menu, menu_item
+ = gtk_menu_item_new_with_label(_("Location")));
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
+ submenu = gtk_menu_new());
+
+ /* Setup the map context menu. */
+ gtk_menu_append(submenu, _cmenu_loc_show_latlon_item
+ = gtk_menu_item_new_with_label(_("Show Lat/Lon")));
+ gtk_menu_append(submenu, _cmenu_loc_clip_latlon_item
+ = gtk_menu_item_new_with_label(_("Copy Lat/Lon to Clipboard")));
+ gtk_menu_append(submenu, gtk_separator_menu_item_new());
+ gtk_menu_append(submenu, _cmenu_loc_route_to_item
+ = gtk_menu_item_new_with_label(_("Download Route to...")));
+ gtk_menu_append(submenu, _cmenu_loc_distance_to_item
+ = gtk_menu_item_new_with_label(_("Show Distance to")));
+ gtk_menu_append(submenu, gtk_separator_menu_item_new());
+ gtk_menu_append(submenu, _cmenu_add_poi
+ = gtk_menu_item_new_with_label(_("Add POI")));
+ gtk_widget_set_sensitive(_cmenu_add_poi, _dbconn);
+ gtk_menu_append(submenu, _cmenu_edit_poi
+ = gtk_menu_item_new_with_label(_("Edit POI")));
+ gtk_widget_set_sensitive(_cmenu_edit_poi, _dbconn);
+
+ /* Setup the waypoint context menu. */
+ gtk_menu_append(menu, menu_item
+ = gtk_menu_item_new_with_label(_("Waypoint")));
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item),
+ submenu = gtk_menu_new());
+
+ gtk_menu_append(submenu, _cmenu_way_show_latlon_item
+ = gtk_menu_item_new_with_label(_("Show Lat/Lon")));
+ gtk_menu_append(submenu, _cmenu_way_show_desc_item
+ = gtk_menu_item_new_with_label(_("Show Description")));
+ gtk_menu_append(submenu, _cmenu_way_clip_latlon_item
+ = gtk_menu_item_new_with_label(_("Copy Lat/Lon to Clipboard")));
+ gtk_menu_append(submenu, _cmenu_way_clip_desc_item
+ = gtk_menu_item_new_with_label(_("Copy Description to Clipboard")));
+ gtk_menu_append(submenu, gtk_separator_menu_item_new());
+ gtk_menu_append(submenu, _cmenu_way_route_to_item
+ = gtk_menu_item_new_with_label(_("Download Route to...")));
+ gtk_menu_append(submenu, _cmenu_way_distance_to_item
+ = gtk_menu_item_new_with_label(_("Show Distance to")));
+ gtk_menu_append(submenu, _cmenu_way_delete_item
+ = gtk_menu_item_new_with_label(_("Delete")));
+
+ /* Connect signals for context menu. */
+ g_signal_connect(G_OBJECT(_cmenu_loc_show_latlon_item), "activate",
+ G_CALLBACK(cmenu_cb_loc_show_latlon), NULL);
+ g_signal_connect(G_OBJECT(_cmenu_loc_clip_latlon_item), "activate",
+ G_CALLBACK(cmenu_cb_loc_clip_latlon), NULL);
+ g_signal_connect(G_OBJECT(_cmenu_loc_route_to_item), "activate",
+ G_CALLBACK(cmenu_cb_loc_route_to), NULL);
+ g_signal_connect(G_OBJECT(_cmenu_loc_distance_to_item), "activate",
+ G_CALLBACK(cmenu_cb_loc_distance_to), NULL);
+ g_signal_connect(G_OBJECT(_cmenu_add_poi), "activate",
+ G_CALLBACK(cmenu_cb_add_poi), NULL);
+ g_signal_connect(G_OBJECT(_cmenu_edit_poi), "activate",
+ G_CALLBACK(cmenu_cb_edit_poi), NULL);
+ g_signal_connect(G_OBJECT(_cmenu_way_show_latlon_item), "activate",
+ G_CALLBACK(cmenu_cb_way_show_latlon), NULL);
+ g_signal_connect(G_OBJECT(_cmenu_way_show_desc_item), "activate",
+ G_CALLBACK(cmenu_cb_way_show_desc), NULL);
+ g_signal_connect(G_OBJECT(_cmenu_way_clip_latlon_item), "activate",
+ G_CALLBACK(cmenu_cb_way_clip_latlon), NULL);
+ g_signal_connect(G_OBJECT(_cmenu_way_clip_desc_item), "activate",
+ G_CALLBACK(cmenu_cb_way_clip_desc), NULL);
+ g_signal_connect(G_OBJECT(_cmenu_way_route_to_item), "activate",
+ G_CALLBACK(cmenu_cb_way_route_to), NULL);
+ g_signal_connect(G_OBJECT(_cmenu_way_distance_to_item), "activate",
+ G_CALLBACK(cmenu_cb_way_distance_to), NULL);
+ g_signal_connect(G_OBJECT(_cmenu_way_delete_item), "activate",
+ G_CALLBACK(cmenu_cb_way_delete), NULL);
- if(SQLITE_OK == sqlite_get_table_printf(_db,
- "select p.lat, p.lon, lower(p.label), lower(c.label)"
- " from poi p, category c "
- " where p.lat between %s and %s "
- " and p.lon between %s and %s "
- " and c.enabled = 1 and p.cat_id = c.cat_id",
- &pszResult, &nRow, &nColumn, NULL,
- slat1, slat2, slon1, slon2))
- {
- for(row=1; row<nRow+1; row++)
- {
- lat1 = g_ascii_strtod(pszResult[row*nColumn+0], NULL);
- lon1 = g_ascii_strtod(pszResult[row*nColumn+1], NULL);
- latlon2unit(lat1, lon1, unitx, unity);
- poix = unit2bufx(unitx);
- poiy = unit2bufy(unity);
+ gtk_widget_show_all(GTK_WIDGET(menu));
- /* Try to get icon for specific POI first. */
- sprintf(buffer, "%s/poi/%s.jpg", _curr_repo->cache_dir,
- pszResult[row*nColumn+2]);
- pixbuf = gdk_pixbuf_new_from_file(buffer, &error);
- if(error)
- {
- /* No icon for specific POI - try for category. */
- error = NULL;
- sprintf(buffer, "%s/poi/%s.jpg", _curr_repo->cache_dir,
- pszResult[row*nColumn+3]);
- pixbuf = gdk_pixbuf_new_from_file(buffer, &error);
- }
- if(error)
- {
- /* No icon for POI or for category - draw default. */
- error = NULL;
- gdk_draw_rectangle(_map_pixmap, _gc_poi, TRUE,
- poix - (int)(0.5f * _draw_line_width),
- poiy - (int)(0.5f * _draw_line_width),
- 3 * _draw_line_width,
- 3 * _draw_line_width);
- }
- else
- {
- gdk_draw_pixbuf(
- _map_pixmap,
- _gc_poi,
- pixbuf,
- 0, 0,
- poix - gdk_pixbuf_get_width(pixbuf) / 2,
- poiy - gdk_pixbuf_get_height(pixbuf) / 2,
- -1,-1,
- GDK_RGB_DITHER_NONE, 0, 0);
- g_object_unref(pixbuf);
- }
- }
- sqlite_free_table(pszResult);
- }
- }
+ gtk_widget_tap_and_hold_setup(_map_widget, GTK_WIDGET(menu), NULL, 0);
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
-static void
-map_render_tile(guint tilex, guint tiley, guint destx, guint desty,
- gboolean fast_fail) {
- gchar buffer[1024];
- GdkPixbuf *pixbuf = NULL;
- GError *error = NULL;
- guint zoff;
+/**
+ * Call gtk_window_present() on Maemo Mapper. This also checks the
+ * configuration and brings up the Settings dialog if the GPS Receiver is
+ * not set up, the first time it is called.
+ */
+static gboolean
+window_present()
+{
+ static gint been_here = 0;
+ printf("%s()\n", __PRETTY_FUNCTION__);
- if(tilex < _world_size_tiles && tiley < _world_size_tiles)
+ if(!been_here++)
{
- /* The tile is possible. */
- vprintf("%s(%u, %u, %u, %u)\n", __PRETTY_FUNCTION__,
- tilex, tiley, destx, desty);
- sprintf(buffer, "%s/%u/%u/%u.jpg",
- _curr_repo->cache_dir, _zoom, tilex, tiley);
- pixbuf = gdk_pixbuf_new_from_file(buffer, &error);
-
- if(error)
- {
- pixbuf = NULL;
- error = NULL;
- }
-
- if(!pixbuf && !fast_fail && _auto_download && *_curr_repo->url
- && !(_zoom % _curr_repo->dl_zoom_steps))
+ /* Set connection state first, to avoid going into this if twice. */
+ if(_rcvr_mac || !_enable_gps || settings_dialog())
{
- map_initiate_download(tilex, tiley, _zoom,
- INITIAL_DOWNLOAD_RETRIES);
- fast_fail = TRUE;
- }
+ gtk_widget_show_all(_window);
+ gps_show_info();
- for(zoff = 1; !pixbuf && (_zoom + zoff) <= MAX_ZOOM
- && zoff <= TILE_SIZE_P2; zoff += 1)
- {
- /* Attempt to blit a wider map. */
- sprintf(buffer, "%s/%u/%u/%u.jpg",
- _curr_repo->cache_dir, _zoom + zoff,
- (tilex >> zoff), (tiley >> zoff));
- pixbuf = gdk_pixbuf_new_from_file(buffer, &error);
- if(error)
- {
- pixbuf = NULL;
- error = NULL;
- }
- if(pixbuf)
- {
- map_pixbuf_scale_inplace(gdk_pixbuf_get_pixels(pixbuf), zoff,
- (tilex - ((tilex >> zoff) << zoff)) << (TILE_SIZE_P2 - zoff),
- (tiley - ((tiley >> zoff) << zoff)) << (TILE_SIZE_P2 - zoff));
- }
- else
- {
- if(_auto_download && *_curr_repo->url
- && !((_zoom + zoff) % _curr_repo->dl_zoom_steps))
- {
- if(!fast_fail)
- map_initiate_download(
- tilex >> zoff, tiley >> zoff, _zoom + zoff,
- INITIAL_DOWNLOAD_RETRIES);
- fast_fail = TRUE;
- }
- }
+ /* Connect to receiver. */
+ if(_enable_gps)
+ rcvr_connect_now();
}
+ else
+ gtk_main_quit();
}
- if(!pixbuf)
- pixbuf = gdk_pixbuf_new(
- GDK_COLORSPACE_RGB,
- FALSE, /* no alpha. */
- 8, /* 8 bits per sample. */
- TILE_SIZE_PIXELS, TILE_SIZE_PIXELS);
- if(pixbuf)
+ gtk_window_present(GTK_WINDOW(_window));
+
+ /* Re-enable any banners that might have been up. */
{
- gdk_draw_pixbuf(
- _map_pixmap,
- _gc_mark,
- pixbuf,
- 0, 0,
- destx, desty,
- TILE_SIZE_PIXELS, TILE_SIZE_PIXELS,
- GDK_RGB_DITHER_NONE, 0, 0);
- g_object_unref(pixbuf);
+ ConnState old_state = _conn_state;
+ set_conn_state(RCVR_OFF);
+ set_conn_state(old_state);
}
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+ return FALSE;
}
/**
- * Force a redraw of the entire _map_pixmap, including fetching the
- * background maps from disk and redrawing the tracks on top of them.
+ * Get the hash value of a ProgressUpdateInfo object. This is trivial, since
+ * the hash is generated and stored when the object is created.
*/
-void
-map_force_redraw()
+static guint
+download_hashfunc(ProgressUpdateInfo *pui)
{
- guint new_x, new_y;
- printf("%s()\n", __PRETTY_FUNCTION__);
-
- for(new_y = 0; new_y < BUF_HEIGHT_TILES; ++new_y)
- for(new_x = 0; new_x < BUF_WIDTH_TILES; ++new_x)
- {
- map_render_tile(
- _base_tilex + new_x,
- _base_tiley + new_y,
- new_x * TILE_SIZE_PIXELS,
- new_y * TILE_SIZE_PIXELS,
- FALSE);
- }
- map_render_paths();
- map_render_poi();
- MACRO_QUEUE_DRAW_AREA();
+ vprintf("%s()\n", __PRETTY_FUNCTION__);
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+ return pui->hash;
}
/**
- * Set the current zoom level. If the given zoom level is the same as the
- * current zoom level, or if the new zoom is invalid
- * (not MIN_ZOOM <= new_zoom < MAX_ZOOM), then this method does nothing.
+ * Return whether or not two ProgressUpdateInfo objects are equal. They
+ * are equal if they are downloading the same tile.
*/
-void
-map_set_zoom(guint new_zoom)
+static gboolean
+download_equalfunc(
+ ProgressUpdateInfo *pui1, ProgressUpdateInfo *pui2)
{
- printf("%s(%d)\n", __PRETTY_FUNCTION__, _zoom);
-
- /* Note that, since new_zoom is a guint and MIN_ZOOM is 0, this if
- * condition also checks for new_zoom >= MIN_ZOOM. */
- if(new_zoom > (MAX_ZOOM - 1))
- return;
- _zoom = new_zoom / _curr_repo->view_zoom_steps
- * _curr_repo->view_zoom_steps;
- _world_size_tiles = unit2tile(WORLD_SIZE_UNITS);
-
- /* If we're leading, update the center to reflect new zoom level. */
- MACRO_RECALC_CENTER(_center.unitx, _center.unity);
-
- /* Update center bounds to reflect new zoom level. */
- _min_center.unitx = pixel2unit(grid2pixel(_screen_grids_halfwidth));
- _min_center.unity = pixel2unit(grid2pixel(_screen_grids_halfheight));
- _max_center.unitx = WORLD_SIZE_UNITS-grid2unit(_screen_grids_halfwidth) - 1;
- _max_center.unity = WORLD_SIZE_UNITS-grid2unit(_screen_grids_halfheight)- 1;
-
- BOUND(_center.unitx, _min_center.unitx, _max_center.unitx);
- BOUND(_center.unity, _min_center.unity, _max_center.unity);
-
- _base_tilex = grid2tile((gint)pixel2grid(
- (gint)unit2pixel((gint)_center.unitx))
- - (gint)_screen_grids_halfwidth);
- _base_tiley = grid2tile(pixel2grid(
- unit2pixel(_center.unity))
- - _screen_grids_halfheight);
-
- /* New zoom level, so we can't reuse the old buffer's pixels. */
+ vprintf("%s()\n", __PRETTY_FUNCTION__);
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+ return pui1->tilex == pui2->tilex && pui1->tiley == pui2->tiley
+ && pui1->zoom == pui2->zoom;
+}
- /* Update state variables. */
- MACRO_RECALC_OFFSET();
- MACRO_RECALC_FOCUS_BASE();
- MACRO_RECALC_FOCUS_SIZE();
+/**
+ * Draw the current mark (representing the current GPS location) onto
+ * _map_widget. This method does not queue the draw area.
+ */
+static void
+map_draw_mark()
+{
+ printf("%s()\n", __PRETTY_FUNCTION__);
- map_set_mark();
- map_force_redraw();
+ if(_enable_gps)
+ {
+ gdk_draw_arc(
+ _map_widget->window,
+ _conn_state == RCVR_FIXED ? _gc_mark : _gc_mark_old,
+ FALSE, /* not filled. */
+ _mark_x1 - _draw_line_width, _mark_y1 - _draw_line_width,
+ 2 * _draw_line_width, 2 * _draw_line_width,
+ 0, 360 * 64);
+ gdk_draw_line(
+ _map_widget->window,
+ _conn_state == RCVR_FIXED
+ ? (_show_velvec ? _gc_mark_velocity : _gc_mark)
+ : _gc_mark_old,
+ _mark_x1, _mark_y1, _mark_x2, _mark_y2);
+ }
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
/**
- * Center the view on the given unitx/unity.
+ * "Set" the mark, which translates the current GPS position into on-screen
+ * units in preparation for drawing the mark with map_draw_mark().
*/
-static void
-map_center_unit(guint new_center_unitx, guint new_center_unity)
+static void map_set_mark()
{
- gint new_base_tilex, new_base_tiley;
- guint new_x, new_y;
- guint j, k, base_new_x, base_old_x, old_x, old_y, iox, ioy;
- printf("%s(%d, %d)\n", __PRETTY_FUNCTION__,
- new_center_unitx, new_center_unity);
-
- /* Assure that _center.unitx/y are bounded. */
- BOUND(new_center_unitx, _min_center.unitx, _max_center.unitx);
- BOUND(new_center_unity, _min_center.unity, _max_center.unity);
-
- _center.unitx = new_center_unitx;
- _center.unity = new_center_unity;
+ printf("%s()\n", __PRETTY_FUNCTION__);
- new_base_tilex = grid2tile((gint)pixel2grid(
- (gint)unit2pixel((gint)_center.unitx))
- - (gint)_screen_grids_halfwidth);
- new_base_tiley = grid2tile(pixel2grid(
- unit2pixel(_center.unity))
- - _screen_grids_halfheight);
+ _mark_x1 = unit2x(_pos.unitx);
+ _mark_y1 = unit2y(_pos.unity);
+ _mark_x2 = _mark_x1 + (_show_velvec ? _vel_offsetx : 0);
+ _mark_y2 = _mark_y1 + (_show_velvec ? _vel_offsety : 0);
+ _mark_minx = MIN(_mark_x1, _mark_x2) - (2 * _draw_line_width);
+ _mark_miny = MIN(_mark_y1, _mark_y2) - (2 * _draw_line_width);
+ _mark_width = abs(_mark_x1 - _mark_x2) + (4 * _draw_line_width);
+ _mark_height = abs(_mark_y1 - _mark_y2) + (4 * _draw_line_width);
- /* Same zoom level, so it's likely that we can reuse some of the old
- * buffer's pixels. */
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
- if(new_base_tilex != _base_tilex
- || new_base_tiley != _base_tiley)
- {
- /* If copying from old parts to new parts, we need to make sure we
- * don't overwrite the old parts when copying, so set up new_x,
- * new_y, old_x, old_y, iox, and ioy with that in mind. */
- if(new_base_tiley < _base_tiley)
- {
- /* New is lower than old - start at bottom and go up. */
- new_y = BUF_HEIGHT_TILES - 1;
- ioy = -1;
- }
- else
- {
- /* New is higher than old - start at top and go down. */
- new_y = 0;
- ioy = 1;
- }
- if(new_base_tilex < _base_tilex)
- {
- /* New is righter than old - start at right and go left. */
- base_new_x = BUF_WIDTH_TILES - 1;
- iox = -1;
- }
- else
- {
- /* New is lefter than old - start at left and go right. */
- base_new_x = 0;
- iox = 1;
- }
+/**
+ * Do an in-place scaling of a pixbuf's pixels at the given ratio from the
+ * given source location. It would have been nice if gdk_pixbuf provided
+ * this method, but I guess it's not general-purpose enough.
+ */
+static void
+map_pixbuf_scale_inplace(guchar *pixels, guint ratio_p2,
+ guint src_x, guint src_y)
+{
+ guint dest_x = 0, dest_y = 0, dest_dim = TILE_SIZE_PIXELS;
+ vprintf("%s(%d, %d, %d)\n", __PRETTY_FUNCTION__, ratio_p2, src_x, src_y);
- /* Iterate over the y tile values. */
- old_y = new_y + new_base_tiley - _base_tiley;
- base_old_x = base_new_x + new_base_tilex - _base_tilex;
- _base_tilex = new_base_tilex;
- _base_tiley = new_base_tiley;
- for(j = 0; j < BUF_HEIGHT_TILES; ++j, new_y += ioy, old_y += ioy)
+ /* Sweep through the entire dest area, copying as necessary, but
+ * DO NOT OVERWRITE THE SOURCE AREA. We'll copy it afterward. */
+ do {
+ guint src_dim = dest_dim >> ratio_p2;
+ guint src_endx = src_x - dest_x + src_dim;
+ gint x, y;
+ for(y = dest_dim - 1; y >= 0; y--)
{
- new_x = base_new_x;
- old_x = base_old_x;
- /* Iterate over the x tile values. */
- for(k = 0; k < BUF_WIDTH_TILES; ++k, new_x += iox, old_x += iox)
+ guint src_offset_y, dest_offset_y;
+ src_offset_y = (src_y + (y >> ratio_p2)) * TILE_PIXBUF_STRIDE;
+ dest_offset_y = (dest_y + y) * TILE_PIXBUF_STRIDE;
+ x = dest_dim - 1;
+ if((unsigned)(dest_y + y - src_y) < src_dim
+ && (unsigned)(dest_x + x - src_x) < src_dim)
+ x -= src_dim;
+ for(; x >= 0; x--)
{
- /* Can we get this grid block from the old buffer?. */
- if(old_x >= 0 && old_x < BUF_WIDTH_TILES
- && old_y >= 0 && old_y < BUF_HEIGHT_TILES)
- {
- /* Copy from old buffer to new buffer. */
- gdk_draw_drawable(
- _map_pixmap,
- _gc_mark,
- _map_pixmap,
- old_x * TILE_SIZE_PIXELS,
- old_y * TILE_SIZE_PIXELS,
- new_x * TILE_SIZE_PIXELS,
- new_y * TILE_SIZE_PIXELS,
- TILE_SIZE_PIXELS, TILE_SIZE_PIXELS);
- }
- else
- {
- map_render_tile(
- new_base_tilex + new_x,
- new_base_tiley + new_y,
- new_x * TILE_SIZE_PIXELS,
- new_y * TILE_SIZE_PIXELS,
- FALSE);
- }
+ guint src_offset, dest_offset;
+ src_offset = src_offset_y + (src_x + (x >> ratio_p2)) * 3;
+ dest_offset = dest_offset_y + (dest_x + x) * 3;
+ pixels[dest_offset + 0] = pixels[src_offset + 0];
+ pixels[dest_offset + 1] = pixels[src_offset + 1];
+ pixels[dest_offset + 2] = pixels[src_offset + 2];
+ if((unsigned)(dest_y + y - src_y) < src_dim && x == src_endx)
+ x -= src_dim;
}
}
- map_render_paths();
- map_render_poi();
+ /* Reuse src_dim and src_endx to store new src_x and src_y. */
+ src_dim = src_x + ((src_x - dest_x) >> ratio_p2);
+ src_endx = src_y + ((src_y - dest_y) >> ratio_p2);
+ dest_x = src_x;
+ dest_y = src_y;
+ src_x = src_dim;
+ src_y = src_endx;
}
-
- MACRO_RECALC_OFFSET();
- MACRO_RECALC_FOCUS_BASE();
-
- map_set_mark();
- MACRO_QUEUE_DRAW_AREA();
+ while((dest_dim >>= ratio_p2) > 1);
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
/**
- * Pan the view by the given number of units in the X and Y directions.
+ * Free a ProgressUpdateInfo data structure that was allocated during the
+ * auto-map-download process.
*/
-void
-map_pan(gint delta_unitx, gint delta_unity)
+static void
+progress_update_info_free(ProgressUpdateInfo *pui)
{
- printf("%s(%d, %d)\n", __PRETTY_FUNCTION__, delta_unitx, delta_unity);
+ vprintf("%s()\n", __PRETTY_FUNCTION__);
- if(_center_mode > 0)
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
- _menu_ac_none_item), TRUE);
- map_center_unit(
- _center.unitx + delta_unitx,
- _center.unity + delta_unity);
+ gnome_vfs_uri_unref((GnomeVFSURI*)pui->src_list->data);
+ g_list_free(pui->src_list);
+ gnome_vfs_uri_unref((GnomeVFSURI*)pui->dest_list->data);
+ g_list_free(pui->dest_list);
+ g_free(pui);
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
/**
- * Initiate a move of the mark from the old location to the current
- * location. This function queues the draw area of the old mark (to force
- * drawing of the background map), then updates the mark, then queus the
- * draw area of the new mark.
+ * Given the xyz coordinates of our map coordinate system, write the qrst
+ * quadtree coordinates to buffer.
*/
static void
-map_move_mark()
+map_convert_coords_to_quadtree_string(int x, int y, int zoomlevel,gchar *buffer)
{
- printf("%s()\n", __PRETTY_FUNCTION__);
+ static const gchar *const quadrant = "qrts";
+ gchar *ptr = buffer;
+ int n;
+ *ptr++ = 't';
+ for(n = 16 - zoomlevel; n >= 0; n--)
+ {
+ int xbit = (x >> n) & 1;
+ int ybit = (y >> n) & 1;
+ *ptr++ = quadrant[xbit + 2 * ybit];
+ }
+ *ptr++ = '\0';
+}
- /* Just queue the old and new draw areas. */
- gtk_widget_queue_draw_area(_map_widget,
- _mark_minx,
- _mark_miny,
- _mark_width,
- _mark_height);
- map_set_mark();
- gtk_widget_queue_draw_area(_map_widget,
- _mark_minx,
- _mark_miny,
- _mark_width,
- _mark_height);
+/**
+ * Construct the URL that we should fetch, based on the current URI format.
+ * This method works differently depending on if a "%s" string is present in
+ * the URI format, since that would indicate a quadtree-based map coordinate
+ * system.
+ */
+static void
+map_construct_url(gchar *buffer, guint tilex, guint tiley, guint zoom)
+{
+ if(strstr(_curr_repo->url, "%s"))
+ {
+ /* This is a satellite-map URI. */
+ gchar location[MAX_ZOOM + 2];
+ map_convert_coords_to_quadtree_string(tilex, tiley, zoom, location);
+ sprintf(buffer, _curr_repo->url, location);
+ }
+ else
+ /* This is a street-map URI. */
+ sprintf(buffer, _curr_repo->url, tilex, tiley, zoom);
+}
+
+
+/**
+ * Initiate a download of the given xyz coordinates using the given buffer
+ * as the URL. If the map already exists on disk, or if we are already
+ * downloading the map, then this method does nothing.
+ */
+static gboolean
+map_initiate_download(guint tilex, guint tiley, guint zoom, gint retries)
+{
+ gchar buffer[1024];
+ GnomeVFSURI *src, *dest;
+ GList *src_list, *dest_list;
+ gint priority;
+ ProgressUpdateInfo *pui;
+ vprintf("%s(%u, %u, %u, %d)\n", __PRETTY_FUNCTION__, tilex, tiley, zoom,
+ retries);
+
+ pui = g_new(ProgressUpdateInfo, 1);
+ pui->hash = tilex + (tiley << 12) + (zoom << 24);
+ pui->tilex = tilex;
+ pui->tiley = tiley;
+ pui->zoom = zoom;
+ if(g_hash_table_lookup(_downloads_hash, pui))
+ {
+ /* Already downloading - return FALSE. */
+ g_free(pui);
+ return FALSE;
+ }
+ sprintf(buffer, "%s/%u/%u/%u.jpg", _curr_repo->cache_dir,
+ zoom, tilex, tiley);
+ dest = gnome_vfs_uri_new(buffer);
+ if(retries > 0 && gnome_vfs_uri_exists(dest))
+ {
+ /* Already downloaded and not overwriting - return FALSE. */
+ gnome_vfs_uri_unref(dest);
+ g_free(pui);
+ return FALSE;
+ }
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
-}
+ /* Priority is based on proximity to _center.unitx - lower number means
+ * higher priority, so the further we are, the higher the number. */
+ priority = GNOME_VFS_PRIORITY_MIN
+ + unit2ptile(abs(tile2punit(tilex, zoom) - _center.unitx)
+ + abs(tile2punit(tiley, zoom) - _center.unity));
+ BOUND(priority, GNOME_VFS_PRIORITY_MIN, GNOME_VFS_PRIORITY_MAX);
-/**
- * Make sure the mark is up-to-date. This function triggers a panning of
- * the view if the mark is appropriately close to the edge of the view.
- */
-static void
-refresh_mark()
-{
- printf("%s()\n", __PRETTY_FUNCTION__);
+ map_construct_url(buffer, tilex, tiley, zoom);
+ src = gnome_vfs_uri_new(buffer);
- guint new_center_unitx;
- guint new_center_unity;
+ src_list = g_list_prepend(src_list = NULL, src);
+ dest_list = g_list_prepend(dest_list = NULL, dest);
- MACRO_RECALC_CENTER(new_center_unitx, new_center_unity);
+ pui->src_list = src_list;
+ pui->dest_list = dest_list;
+ pui->retries_left = retries;
- if((new_center_unitx - _focus.unitx) < _focus_unitwidth
- && (new_center_unity - _focus.unity) < _focus_unitheight)
- /* We're not changing the view - just move the mark. */
- map_move_mark();
+ /* Initiate asynchronous download. */
+ if(retries)
+ {
+ /* This is a download; if retries < 0, then this is an overwrite */
+ if(GNOME_VFS_OK != gnome_vfs_async_xfer(
+ &pui->handle,
+ src_list, dest_list,
+ retries < 0 ? GNOME_VFS_XFER_DEFAULT
+ : GNOME_VFS_XFER_USE_UNIQUE_NAMES,
+ GNOME_VFS_XFER_ERROR_MODE_QUERY,
+ retries < 0 ? GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE
+ : GNOME_VFS_XFER_OVERWRITE_MODE_QUERY,
+ priority,
+ (GnomeVFSAsyncXferProgressCallback)map_download_cb_async,
+ pui,
+ (GnomeVFSXferProgressCallback)gtk_true,
+ NULL))
+ {
+ progress_update_info_free(pui);
+ return FALSE;
+ }
+ }
else
- map_center_unit(new_center_unitx, new_center_unity);
+ {
+ /* This is a deletion. */
+ if(GNOME_VFS_OK != gnome_vfs_async_xfer(
+ &pui->handle,
+ dest_list, NULL,
+ GNOME_VFS_XFER_DELETE_ITEMS,
+ GNOME_VFS_XFER_ERROR_MODE_QUERY,
+ GNOME_VFS_XFER_OVERWRITE_MODE_QUERY,
+ priority,
+ (GnomeVFSAsyncXferProgressCallback)map_download_cb_async,
+ pui,
+ (GnomeVFSXferProgressCallback)gtk_true,
+ NULL))
+ {
+ progress_update_info_free(pui);
+ return FALSE;
+ }
+ }
+
+ g_hash_table_insert(_downloads_hash, pui, pui);
+ if(!_num_downloads++ && !_download_banner)
+ _download_banner = hildon_banner_show_progress(
+ _window, NULL, _("Downloading maps"));
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+ return TRUE;
}
-/**
- * Handle a start tag in the parsing of a GPX file.
- */
-#define MACRO_SET_UNKNOWN() { \
- data->prev_state = data->state; \
- data->state = UNKNOWN; \
- data->unknown_depth = 1; \
-}
static void
-gpx_start_element(SaxData *data, const xmlChar *name, const xmlChar **attrs)
+map_render_poi()
{
- vprintf("%s(%s)\n", __PRETTY_FUNCTION__, name);
+ guint unitx, unity;
+ gfloat lat1, lat2, lon1, lon2, tmp;
+ gchar slat1[10], slat2[10], slon1[10], slon2[10];
+ gchar buffer[100];
+ gchar **pszResult;
+ gint nRow, nColumn, row, poix, poiy;
+ GdkPixbuf *pixbuf = NULL;
+ GError *error = NULL;
- switch(data->state)
+ if(_db && _poi_zoom > _zoom)
{
- case ERROR:
- break;
- case START:
- if(!strcmp((gchar*)name, "gpx"))
- data->state = INSIDE_GPX;
- else
- MACRO_SET_UNKNOWN();
- break;
- case INSIDE_GPX:
- if(!strcmp((gchar*)name, "trk"))
- data->state = INSIDE_PATH;
- else
- MACRO_SET_UNKNOWN();
- break;
- case INSIDE_PATH:
- if(!strcmp((gchar*)name, "trkseg"))
- {
- data->state = INSIDE_PATH_SEGMENT;
- data->at_least_one_trkpt = FALSE;
- }
- else
- MACRO_SET_UNKNOWN();
- break;
- case INSIDE_PATH_SEGMENT:
- if(!strcmp((gchar*)name, "trkpt"))
+ unitx = x2unit(1);
+ unity = y2unit(1);
+ unit2latlon(unitx, unity, lat1, lon1);
+ unitx = x2unit(BUF_WIDTH_PIXELS);
+ unity = y2unit(BUF_HEIGHT_PIXELS);
+ unit2latlon(unitx, unity, lat2, lon2);
+ if(lat1 > lat2)
+ {
+ tmp = lat2;
+ lat2 = lat1;
+ lat1 = tmp;
+ }
+ if(lon1 > lon2)
+ {
+ tmp = lon2;
+ lon2 = lon1;
+ lon1 = tmp;
+ }
+
+ g_ascii_dtostr(slat1, sizeof(slat1), lat1);
+ g_ascii_dtostr(slat2, sizeof(slat2), lat2);
+ g_ascii_dtostr(slon1, sizeof(slon1), lon1);
+ g_ascii_dtostr(slon2, sizeof(slon2), lon2);
+
+ if(SQLITE_OK == sqlite_get_table_printf(_db,
+ "select p.lat, p.lon, lower(p.label), lower(c.label)"
+ " from poi p, category c "
+ " where p.lat between %s and %s "
+ " and p.lon between %s and %s "
+ " and c.enabled = 1 and p.cat_id = c.cat_id",
+ &pszResult, &nRow, &nColumn, NULL,
+ slat1, slat2, slon1, slon2))
+ {
+ for(row=1; row<nRow+1; row++)
{
- const xmlChar **curr_attr;
- gchar *error_check;
- gfloat lat = 0.f, lon = 0.f;
- gboolean has_lat, has_lon;
- has_lat = FALSE;
- has_lon = FALSE;
- for(curr_attr = attrs; *curr_attr != NULL; )
+ lat1 = g_ascii_strtod(pszResult[row*nColumn+0], NULL);
+ lon1 = g_ascii_strtod(pszResult[row*nColumn+1], NULL);
+ latlon2unit(lat1, lon1, unitx, unity);
+ poix = unit2bufx(unitx);
+ poiy = unit2bufy(unity);
+
+ /* Try to get icon for specific POI first. */
+ sprintf(buffer, "%s/poi/%s.jpg", _curr_repo->cache_dir,
+ pszResult[row*nColumn+2]);
+ pixbuf = gdk_pixbuf_new_from_file(buffer, &error);
+ if(error)
{
- const gchar *attr_name = *curr_attr++;
- const gchar *attr_val = *curr_attr++;
- if(!strcmp(attr_name, "lat"))
- {
- lat = g_ascii_strtod(attr_val, &error_check);
- if(error_check != attr_val)
- has_lat = TRUE;
- }
- else if(!strcmp(attr_name, "lon"))
- {
- lon = g_ascii_strtod(attr_val, &error_check);
- if(error_check != attr_val)
- has_lon = TRUE;
- }
+ /* No icon for specific POI - try for category. */
+ error = NULL;
+ sprintf(buffer, "%s/poi/%s.jpg", _curr_repo->cache_dir,
+ pszResult[row*nColumn+3]);
+ pixbuf = gdk_pixbuf_new_from_file(buffer, &error);
}
- if(has_lat && has_lon)
+ if(error)
{
- if(data->path.path_type == TRACK)
- {
- MACRO_TRACK_INCREMENT_TAIL(data->path.path.track);
- latlon2unit(lat, lon,
- data->path.path.track.tail->point.unitx,
- data->path.path.track.tail->point.unity);
- data->path.path.track.tail->time = 0;
- }
- else
- {
- MACRO_ROUTE_INCREMENT_TAIL(data->path.path.route);
- latlon2unit(lat, lon,
- data->path.path.route.tail->unitx,
- data->path.path.route.tail->unity);
- }
- data->state = INSIDE_PATH_POINT;
- }
- else
- data->state = ERROR;
- }
- else
- MACRO_SET_UNKNOWN();
- break;
- case INSIDE_PATH_POINT:
- /* only parse time for tracks */
- if(data->path.path_type == TRACK
- && !strcmp((gchar*)name, "time"))
- data->state = INSIDE_PATH_POINT_TIME;
-
- /* only parse description for routes */
- else if(data->path.path_type == ROUTE
- && !strcmp((gchar*)name, "desc"))
- data->state = INSIDE_PATH_POINT_DESC;
-
- else
- MACRO_SET_UNKNOWN();
- break;
- case UNKNOWN:
- data->unknown_depth++;
- break;
- default:
- ;
+ /* No icon for POI or for category - draw default. */
+ error = NULL;
+ gdk_draw_rectangle(_map_pixmap, _gc_poi, TRUE,
+ poix - (int)(0.5f * _draw_line_width),
+ poiy - (int)(0.5f * _draw_line_width),
+ 3 * _draw_line_width,
+ 3 * _draw_line_width);
+ }
+ else
+ {
+ gdk_draw_pixbuf(
+ _map_pixmap,
+ _gc_poi,
+ pixbuf,
+ 0, 0,
+ poix - gdk_pixbuf_get_width(pixbuf) / 2,
+ poiy - gdk_pixbuf_get_height(pixbuf) / 2,
+ -1,-1,
+ GDK_RGB_DITHER_NONE, 0, 0);
+ g_object_unref(pixbuf);
+ }
+ }
+ sqlite_free_table(pszResult);
+ }
}
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
-/**
- * Handle an end tag in the parsing of a GPX file.
- */
static void
-gpx_end_element(SaxData *data, const xmlChar *name)
-{
- vprintf("%s(%s)\n", __PRETTY_FUNCTION__, name);
+map_render_tile(guint tilex, guint tiley, guint destx, guint desty,
+ gboolean fast_fail) {
+ gchar buffer[1024];
+ GdkPixbuf *pixbuf = NULL;
+ GError *error = NULL;
+ guint zoff;
- switch(data->state)
+ if(tilex < _world_size_tiles && tiley < _world_size_tiles)
{
- case ERROR:
- break;
- case START:
- data->state = ERROR;
- break;
- case INSIDE_GPX:
- if(!strcmp((gchar*)name, "gpx"))
- data->state = FINISH;
- else
- data->state = ERROR;
- break;
- case INSIDE_PATH:
- if(!strcmp((gchar*)name, "trk"))
- data->state = INSIDE_GPX;
- else
- data->state = ERROR;
- break;
- case INSIDE_PATH_SEGMENT:
- if(!strcmp((gchar*)name, "trkseg"))
+ /* The tile is possible. */
+ vprintf("%s(%u, %u, %u, %u)\n", __PRETTY_FUNCTION__,
+ tilex, tiley, destx, desty);
+ sprintf(buffer, "%s/%u/%u/%u.jpg",
+ _curr_repo->cache_dir, _zoom, tilex, tiley);
+ pixbuf = gdk_pixbuf_new_from_file(buffer, &error);
+
+ if(error)
+ {
+ pixbuf = NULL;
+ error = NULL;
+ }
+
+ if(!pixbuf && !fast_fail && _auto_download && *_curr_repo->url
+ && !(_zoom % _curr_repo->dl_zoom_steps))
+ {
+ map_initiate_download(tilex, tiley, _zoom,
+ INITIAL_DOWNLOAD_RETRIES);
+ fast_fail = TRUE;
+ }
+
+ for(zoff = 1; !pixbuf && (_zoom + zoff) <= MAX_ZOOM
+ && zoff <= TILE_SIZE_P2; zoff += 1)
+ {
+ /* Attempt to blit a wider map. */
+ sprintf(buffer, "%s/%u/%u/%u.jpg",
+ _curr_repo->cache_dir, _zoom + zoff,
+ (tilex >> zoff), (tiley >> zoff));
+ pixbuf = gdk_pixbuf_new_from_file(buffer, &error);
+ if(error)
{
- if(data->at_least_one_trkpt)
- {
- if(data->path.path_type == TRACK)
- {
- MACRO_TRACK_INCREMENT_TAIL(data->path.path.track);
- *data->path.path.track.tail = _track_null;
- }
- else
- {
- MACRO_ROUTE_INCREMENT_TAIL(data->path.path.route);
- *data->path.path.route.tail = _pos_null;
- }
- }
- data->state = INSIDE_PATH;
+ pixbuf = NULL;
+ error = NULL;
}
- else
- data->state = ERROR;
- break;
- case INSIDE_PATH_POINT:
- if(!strcmp((gchar*)name, "trkpt"))
+ if(pixbuf)
{
- data->state = INSIDE_PATH_SEGMENT;
- data->at_least_one_trkpt = TRUE;
+ map_pixbuf_scale_inplace(gdk_pixbuf_get_pixels(pixbuf), zoff,
+ (tilex - ((tilex >> zoff) << zoff)) << (TILE_SIZE_P2 - zoff),
+ (tiley - ((tiley >> zoff) << zoff)) << (TILE_SIZE_P2 - zoff));
}
else
- data->state = ERROR;
- break;
- case INSIDE_PATH_POINT_TIME:
- /* only parse time for tracks */
- if(!strcmp((gchar*)name, "time"))
{
- struct tm time;
- gchar *ptr;
-
- if(NULL == (ptr = strptime(data->chars->str,
- XML_DATE_FORMAT, &time)))
- /* Failed to parse dateTime format. */
- data->state = ERROR;
- else
+ if(_auto_download && *_curr_repo->url
+ && !((_zoom + zoff) % _curr_repo->dl_zoom_steps))
{
- /* Parse was successful. Now we have to parse timezone.
- * From here on, if there is an error, I just assume local
- * timezone. Yes, this is not proper XML, but I don't
- * care. */
- gchar *error_check;
-
- /* First, set time in "local" time zone. */
- data->path.path.track.tail->time = (mktime(&time));
-
- /* Now, skip inconsequential characters */
- while(*ptr && *ptr != 'Z' && *ptr != '-' && *ptr != '+')
- ptr++;
-
- /* Check if we ran to the end of the string. */
- if(*ptr)
- {
- /* Next character is either 'Z', '-', or '+' */
- if(*ptr == 'Z')
- /* Zulu (UTC) time. Undo the local time zone's
- * offset. */
- data->path.path.track.tail->time += time.tm_gmtoff;
- else
- {
- /* Not Zulu (UTC). Must parse hours and minutes. */
- gint offhours = strtol(ptr, &error_check, 10);
- if(error_check != ptr
- && *(ptr = error_check) == ':')
- {
- /* Parse of hours worked. Check minutes. */
- gint offmins = strtol(ptr + 1,
- &error_check, 10);
- if(error_check != (ptr + 1))
- {
- /* Parse of minutes worked. Calculate. */
- data->path.path.track.tail->time
- += (time.tm_gmtoff
- - (offhours * 60 * 60
- + offmins * 60));
- }
- }
- }
- }
- /* Successfully parsed dateTime. */
- data->state = INSIDE_PATH_POINT;
+ if(!fast_fail)
+ map_initiate_download(
+ tilex >> zoff, tiley >> zoff, _zoom + zoff,
+ INITIAL_DOWNLOAD_RETRIES);
+ fast_fail = TRUE;
}
-
- g_string_free(data->chars, TRUE);
- data->chars = g_string_new("");
- }
- else
- data->state = ERROR;
- break;
- case INSIDE_PATH_POINT_DESC:
- /* only parse description for routes */
- if(!strcmp((gchar*)name, "desc"))
- {
- MACRO_ROUTE_INCREMENT_WTAIL(data->path.path.route);
- data->path.path.route.wtail->point = data->path.path.route.tail;
- data->path.path.route.wtail->desc
- = g_string_free(data->chars, FALSE);
- data->chars = g_string_new("");
- data->state = INSIDE_PATH_POINT;
}
- else
- data->state = ERROR;
- break;
- case UNKNOWN:
- if(!--data->unknown_depth)
- data->state = data->prev_state;
- else
- data->state = ERROR;
- break;
- default:
- ;
+ }
+ }
+ if(pixbuf)
+ {
+ gdk_draw_pixbuf(
+ _map_pixmap,
+ _gc_mark,
+ pixbuf,
+ 0, 0,
+ destx, desty,
+ TILE_SIZE_PIXELS, TILE_SIZE_PIXELS,
+ GDK_RGB_DITHER_NONE, 0, 0);
+ g_object_unref(pixbuf);
+ }
+ else
+ {
+ gdk_draw_rectangle(_map_pixmap, _map_widget->style->black_gc, TRUE,
+ destx, desty,
+ TILE_SIZE_PIXELS, TILE_SIZE_PIXELS);
}
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
/**
- * Handle char data in the parsing of a GPX file.
+ * Force a redraw of the entire _map_pixmap, including fetching the
+ * background maps from disk and redrawing the tracks on top of them.
*/
-static void
-gpx_chars(SaxData *data, const xmlChar *ch, int len)
+void
+map_force_redraw()
{
- guint i;
- vprintf("%s()\n", __PRETTY_FUNCTION__);
+ guint new_x, new_y;
+ printf("%s()\n", __PRETTY_FUNCTION__);
- switch(data->state)
- {
- case ERROR:
- case UNKNOWN:
- break;
- case INSIDE_PATH_POINT_TIME:
- case INSIDE_PATH_POINT_DESC:
- for(i = 0; i < len; i++)
- data->chars = g_string_append_c(data->chars, ch[i]);
- vprintf("%s\n", data->chars->str);
- break;
- default:
- break;
- }
+ for(new_y = 0; new_y < BUF_HEIGHT_TILES; ++new_y)
+ for(new_x = 0; new_x < BUF_WIDTH_TILES; ++new_x)
+ {
+ map_render_tile(
+ _base_tilex + new_x,
+ _base_tiley + new_y,
+ new_x * TILE_SIZE_PIXELS,
+ new_y * TILE_SIZE_PIXELS,
+ FALSE);
+ }
+ map_render_paths();
+ map_render_poi();
+ MACRO_QUEUE_DRAW_AREA();
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
/**
- * Handle an entity in the parsing of a GPX file. We don't do anything
- * special here.
+ * Set the current zoom level. If the given zoom level is the same as the
+ * current zoom level, or if the new zoom is invalid
+ * (not MIN_ZOOM <= new_zoom < MAX_ZOOM), then this method does nothing.
*/
-static xmlEntityPtr
-gpx_get_entity(SaxData *data, const xmlChar *name)
+void
+map_set_zoom(guint new_zoom)
{
- vprintf("%s()\n", __PRETTY_FUNCTION__);
- vprintf("%s(): return\n", __PRETTY_FUNCTION__);
- return xmlGetPredefinedEntity(name);
-}
+ printf("%s(%d)\n", __PRETTY_FUNCTION__, _zoom);
+
+ /* Note that, since new_zoom is a guint and MIN_ZOOM is 0, this if
+ * condition also checks for new_zoom >= MIN_ZOOM. */
+ if(new_zoom > (MAX_ZOOM - 1))
+ return;
+ _zoom = new_zoom / _curr_repo->view_zoom_steps
+ * _curr_repo->view_zoom_steps;
+ _world_size_tiles = unit2tile(WORLD_SIZE_UNITS);
+
+ /* If we're leading, update the center to reflect new zoom level. */
+ MACRO_RECALC_CENTER(_center.unitx, _center.unity);
+
+ /* Update center bounds to reflect new zoom level. */
+ _min_center.unitx = pixel2unit(grid2pixel(_screen_grids_halfwidth));
+ _min_center.unity = pixel2unit(grid2pixel(_screen_grids_halfheight));
+ _max_center.unitx = WORLD_SIZE_UNITS-grid2unit(_screen_grids_halfwidth) - 1;
+ _max_center.unity = WORLD_SIZE_UNITS-grid2unit(_screen_grids_halfheight)- 1;
+
+ BOUND(_center.unitx, _min_center.unitx, _max_center.unitx);
+ BOUND(_center.unity, _min_center.unity, _max_center.unity);
+
+ _base_tilex = grid2tile((gint)pixel2grid(
+ (gint)unit2pixel((gint)_center.unitx))
+ - (gint)_screen_grids_halfwidth);
+ _base_tiley = grid2tile(pixel2grid(
+ unit2pixel(_center.unity))
+ - _screen_grids_halfheight);
+
+ /* New zoom level, so we can't reuse the old buffer's pixels. */
+
+
+ /* Update state variables. */
+ MACRO_RECALC_OFFSET();
+ MACRO_RECALC_FOCUS_BASE();
+ MACRO_RECALC_FOCUS_SIZE();
+
+ map_set_mark();
+ map_force_redraw();
-/**
- * Handle an error in the parsing of a GPX file.
- */
-static void
-gpx_error(SaxData *data, const gchar *msg, ...)
-{
- vprintf("%s()\n", __PRETTY_FUNCTION__);
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
- data->state = ERROR;
}
/**
- * Parse the given character buffer of the given size, replacing the given
- * Track's pointers with pointers to new arrays depending on the given
- * policy, adding extra_bins slots in the arrays for new data.
- *
- * policy_old should be negative to indicate that the existing data should
- * be prepended to the new GPX data, positive to indicate the opposite, and
- * zero to indicate that we should throw away the old data.
- *
- * When importing tracks, we *prepend* the GPX data and provide extra_bins.
- * When importing routes, we *append* in the case of regular routes, and we
- * *replace* in the case of automatic routing. Routes get no extra bins.
+ * Center the view on the given unitx/unity.
*/
-static gboolean
-parse_track_gpx(gchar *buffer, gint size, gint policy_old)
+static void
+map_center_unit(guint new_center_unitx, guint new_center_unity)
{
- SaxData data;
- xmlSAXHandler sax_handler;
- printf("%s()\n", __PRETTY_FUNCTION__);
+ gint new_base_tilex, new_base_tiley;
+ guint new_x, new_y;
+ guint j, k, base_new_x, base_old_x, old_x, old_y, iox, ioy;
+ printf("%s(%d, %d)\n", __PRETTY_FUNCTION__,
+ new_center_unitx, new_center_unity);
- data.path.path_type = TRACK;
- MACRO_INIT_TRACK(data.path.path.track);
- data.state = START;
- data.chars = g_string_new("");
+ /* Assure that _center.unitx/y are bounded. */
+ BOUND(new_center_unitx, _min_center.unitx, _max_center.unitx);
+ BOUND(new_center_unity, _min_center.unity, _max_center.unity);
- memset(&sax_handler, 0, sizeof(sax_handler));
- sax_handler.characters = (charactersSAXFunc)gpx_chars;
- sax_handler.startElement = (startElementSAXFunc)gpx_start_element;
- sax_handler.endElement = (endElementSAXFunc)gpx_end_element;
- sax_handler.entityDecl = (entityDeclSAXFunc)gpx_get_entity;
- sax_handler.warning = (warningSAXFunc)gpx_error;
- sax_handler.error = (errorSAXFunc)gpx_error;
- sax_handler.fatalError = (fatalErrorSAXFunc)gpx_error;
+ _center.unitx = new_center_unitx;
+ _center.unity = new_center_unity;
- xmlSAXUserParseMemory(&sax_handler, &data, buffer, size);
- g_string_free(data.chars, TRUE);
+ new_base_tilex = grid2tile((gint)pixel2grid(
+ (gint)unit2pixel((gint)_center.unitx))
+ - (gint)_screen_grids_halfwidth);
+ new_base_tiley = grid2tile(pixel2grid(
+ unit2pixel(_center.unity))
+ - _screen_grids_halfheight);
- if(data.state != FINISH)
- {
- vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
- return FALSE;
- }
+ /* Same zoom level, so it's likely that we can reuse some of the old
+ * buffer's pixels. */
- /* Successful parsing - replace given Track structure. */
- if(policy_old && _track.head)
+ if(new_base_tilex != _base_tilex
+ || new_base_tiley != _base_tiley)
{
- TrackPoint *src_first;
- Track *src, *dest;
-
- if(policy_old > 0)
+ /* If copying from old parts to new parts, we need to make sure we
+ * don't overwrite the old parts when copying, so set up new_x,
+ * new_y, old_x, old_y, iox, and ioy with that in mind. */
+ if(new_base_tiley < _base_tiley)
{
- /* Append to current track. */
- src = &data.path.path.track;
- dest = &_track;
+ /* New is lower than old - start at bottom and go up. */
+ new_y = BUF_HEIGHT_TILES - 1;
+ ioy = -1;
}
else
{
- /* Prepend to current track. */
- src = &_track;
- dest = &data.path.path.track;
+ /* New is higher than old - start at top and go down. */
+ new_y = 0;
+ ioy = 1;
}
-
- /* Find src_first non-zero point. */
- for(src_first = src->head - 1; src_first++ != src->tail; )
- if(src_first->point.unity)
- break;
-
- /* Append track points from src to dest. */
- if(src->tail >= src_first)
+ if(new_base_tilex < _base_tilex)
{
- guint num_dest_points = dest->tail - dest->head + 1;
- guint num_src_points = src->tail - src_first + 1;
-
- /* Adjust dest->tail to be able to fit src track data
- * plus room for more track data. */
- track_resize(dest,
- num_dest_points + num_src_points + ARRAY_CHUNK_SIZE);
-
- memcpy(dest->tail + 1, src_first,
- num_src_points * sizeof(TrackPoint));
-
- dest->tail += num_src_points;
+ /* New is righter than old - start at right and go left. */
+ base_new_x = BUF_WIDTH_TILES - 1;
+ iox = -1;
+ }
+ else
+ {
+ /* New is lefter than old - start at left and go right. */
+ base_new_x = 0;
+ iox = 1;
}
- MACRO_CLEAR_TRACK(*src);
- if(policy_old < 0)
- _track = *dest;
- }
- else
- {
- MACRO_CLEAR_TRACK(_track);
- /* Overwrite with data.track. */
- _track = data.path.path.track;
- track_resize(&_track,
- _track.tail - _track.head + 1 + ARRAY_CHUNK_SIZE);
+ /* Iterate over the y tile values. */
+ old_y = new_y + new_base_tiley - _base_tiley;
+ base_old_x = base_new_x + new_base_tilex - _base_tilex;
+ _base_tilex = new_base_tilex;
+ _base_tiley = new_base_tiley;
+ for(j = 0; j < BUF_HEIGHT_TILES; ++j, new_y += ioy, old_y += ioy)
+ {
+ new_x = base_new_x;
+ old_x = base_old_x;
+ /* Iterate over the x tile values. */
+ for(k = 0; k < BUF_WIDTH_TILES; ++k, new_x += iox, old_x += iox)
+ {
+ /* Can we get this grid block from the old buffer?. */
+ if(old_x >= 0 && old_x < BUF_WIDTH_TILES
+ && old_y >= 0 && old_y < BUF_HEIGHT_TILES)
+ {
+ /* Copy from old buffer to new buffer. */
+ gdk_draw_drawable(
+ _map_pixmap,
+ _gc_mark,
+ _map_pixmap,
+ old_x * TILE_SIZE_PIXELS,
+ old_y * TILE_SIZE_PIXELS,
+ new_x * TILE_SIZE_PIXELS,
+ new_y * TILE_SIZE_PIXELS,
+ TILE_SIZE_PIXELS, TILE_SIZE_PIXELS);
+ }
+ else
+ {
+ map_render_tile(
+ new_base_tilex + new_x,
+ new_base_tiley + new_y,
+ new_x * TILE_SIZE_PIXELS,
+ new_y * TILE_SIZE_PIXELS,
+ FALSE);
+ }
+ }
+ }
+ map_render_paths();
+ map_render_poi();
}
- vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
- return TRUE;
-}
-
-static gboolean
-parse_route_gpx(gchar *buffer, gint size, gint policy_old)
-{
- SaxData data;
- xmlSAXHandler sax_handler;
- printf("%s()\n", __PRETTY_FUNCTION__);
-
- data.path.path_type = ROUTE;
- MACRO_INIT_ROUTE(data.path.path.route);
- data.state = START;
- data.chars = g_string_new("");
-
- memset(&sax_handler, 0, sizeof(sax_handler));
- sax_handler.characters = (charactersSAXFunc)gpx_chars;
- sax_handler.startElement = (startElementSAXFunc)gpx_start_element;
- sax_handler.endElement = (endElementSAXFunc)gpx_end_element;
- sax_handler.entityDecl = (entityDeclSAXFunc)gpx_get_entity;
- sax_handler.warning = (warningSAXFunc)gpx_error;
- sax_handler.error = (errorSAXFunc)gpx_error;
- sax_handler.fatalError = (fatalErrorSAXFunc)gpx_error;
-
- xmlSAXUserParseMemory(&sax_handler, &data, buffer, size);
- g_string_free(data.chars, TRUE);
+ MACRO_RECALC_OFFSET();
+ MACRO_RECALC_FOCUS_BASE();
- if(data.state != FINISH)
- {
- vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
- return FALSE;
- }
+ map_set_mark();
+ MACRO_QUEUE_DRAW_AREA();
- if(policy_old && _route.head)
- {
- Point *src_first;
- Route *src, *dest;
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
- if(policy_old > 0)
- {
- /* Append to current route. */
- src = &data.path.path.route;
- dest = &_route;
- }
- else
- {
- /* Prepend to current route. */
- src = &_route;
- dest = &data.path.path.route;
- }
+/**
+ * Pan the view by the given number of units in the X and Y directions.
+ */
+void
+map_pan(gint delta_unitx, gint delta_unity)
+{
+ printf("%s(%d, %d)\n", __PRETTY_FUNCTION__, delta_unitx, delta_unity);
- /* Find src_first non-zero point. */
- for(src_first = src->head - 1; src_first++ != src->tail; )
- if(src_first->unity)
- break;
+ if(_center_mode > 0)
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
+ _menu_ac_none_item), TRUE);
+ map_center_unit(
+ _center.unitx + delta_unitx,
+ _center.unity + delta_unity);
- /* Append route points from src to dest. */
- if(src->tail >= src_first)
- {
- WayPoint *curr;
- guint num_dest_points = dest->tail - dest->head + 1;
- guint num_src_points = src->tail - src_first + 1;
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
- /* Adjust dest->tail to be able to fit src route data
- * plus room for more route data. */
- route_resize(dest, num_dest_points + num_src_points);
+/**
+ * Initiate a move of the mark from the old location to the current
+ * location. This function queues the draw area of the old mark (to force
+ * drawing of the background map), then updates the mark, then queus the
+ * draw area of the new mark.
+ */
+static void
+map_move_mark()
+{
+ printf("%s()\n", __PRETTY_FUNCTION__);
- memcpy(dest->tail + 1, src_first,
- num_src_points * sizeof(Point));
+ /* Just queue the old and new draw areas. */
+ gtk_widget_queue_draw_area(_map_widget,
+ _mark_minx,
+ _mark_miny,
+ _mark_width,
+ _mark_height);
+ map_set_mark();
+ gtk_widget_queue_draw_area(_map_widget,
+ _mark_minx,
+ _mark_miny,
+ _mark_width,
+ _mark_height);
- dest->tail += num_src_points;
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
+}
- /* Append waypoints from src to dest->. */
- route_wresize(dest, (dest->wtail - dest->whead)
- + (src->wtail - src->whead) + 2);
- for(curr = src->whead - 1; curr++ != src->wtail; )
- {
- (++(dest->wtail))->point = dest->head + num_dest_points
- + (curr->point - src_first);
- dest->wtail->desc = curr->desc;
- }
+/**
+ * Make sure the mark is up-to-date. This function triggers a panning of
+ * the view if the mark is appropriately close to the edge of the view.
+ */
+static void
+refresh_mark()
+{
+ printf("%s()\n", __PRETTY_FUNCTION__);
- }
+ guint new_center_unitx;
+ guint new_center_unity;
- /* Kill old route - don't use MACRO_CLEAR_ROUTE(), because that
- * would free the string desc's that we just moved to data.route. */
- g_free(src->head);
- g_free(src->whead);
- if(policy_old < 0)
- _route = *dest;
- }
+ MACRO_RECALC_CENTER(new_center_unitx, new_center_unity);
+
+ if((new_center_unitx - _focus.unitx) < _focus_unitwidth
+ && (new_center_unity - _focus.unity) < _focus_unitheight)
+ /* We're not changing the view - just move the mark. */
+ map_move_mark();
else
- {
- MACRO_CLEAR_ROUTE(_route);
- /* Overwrite with data.route. */
- _route = data.path.path.route;
- route_resize(&_route, _route.tail - _route.head + 1);
- }
+ map_center_unit(new_center_unitx, new_center_unity);
- vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
- return TRUE;
+ vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
/**
ESCAPE_KEY_TEXT[ESCAPE_KEY_TOGGLE_GPS] = _("Toggle GPS");
ESCAPE_KEY_TEXT[ESCAPE_KEY_TOGGLE_GPSINFO] = _("Toggle GPS Info");
+ /* Set up track array (must be done before config). */
+ memset(&_track, 0, sizeof(_track));
+ memset(&_route, 0, sizeof(_route));
+ MACRO_INIT_TRACK(_track);
+
config_init();
/* Initialize _program. */
_gmtoffset = time2.tm_gmtoff;
}
- memset(&_track, 0, sizeof(_track));
- memset(&_route, 0, sizeof(_route));
_last_spoken_phrase = g_strdup("");
- /* Set up track array. */
- MACRO_INIT_TRACK(_track);
-
_downloads_hash = g_hash_table_new((GHashFunc)download_hashfunc,
(GEqualFunc)download_equalfunc);
memset(&_autoroute_data, 0, sizeof(_autoroute_data));
gnome_vfs_init();
+ /* Initialize localization. */
+ setlocale(LC_ALL, "");
+ bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
+ bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
+ textdomain(GETTEXT_PACKAGE);
+
maemo_mapper_init(argc, argv);
if(OSSO_OK != osso_rpc_set_default_cb_f(_osso, dbus_cb_default, NULL))
printf("%s()\n", __PRETTY_FUNCTION__);
if(open_file(&buffer, NULL, &size, &_route_dir_uri, NULL,
- GTK_FILE_CHOOSER_ACTION_OPEN))
- {
- /* If auto is enabled, append the route, otherwise replace it. */
- if(parse_route_gpx(buffer, size, _autoroute_data.enabled ? 0 : 1))
- {
- cancel_autoroute();
-
- /* Find the nearest route point, if we're connected. */
- route_find_nearest_point();
-
- map_force_redraw();
- hildon_banner_show_information(_window, NULL,
- _("Route Opened"));
- }
- else
- popup_error(_window, _("Error parsing GPX file."));
- g_free(buffer);
- }
-
- vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
- return TRUE;
-}
-
-static gboolean
-menu_cb_route_reset(GtkAction *action)
-{
- printf("%s()\n", __PRETTY_FUNCTION__);
-
- if(_route.head)
- {
- route_find_nearest_point();
- map_render_paths();
- map_render_poi();
- MACRO_QUEUE_DRAW_AREA();
- }
-
- vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
- return TRUE;
-}
-
-static gboolean
-menu_cb_route_clear(GtkAction *action)
-{
- printf("%s()\n", __PRETTY_FUNCTION__);
-
- _next_way_dist_rough = -1; /* to avoid announcement attempts. */
- cancel_autoroute();
- MACRO_CLEAR_TRACK(_route);
- map_force_redraw();
-
- vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
- return TRUE;
-}
-
-static gboolean
-menu_cb_track_open(GtkAction *action)
-{
- gchar *buffer;
- gint size;
- printf("%s()\n", __PRETTY_FUNCTION__);
-
- if(open_file(&buffer, NULL, &size, NULL, &_track_file_uri,
- GTK_FILE_CHOOSER_ACTION_OPEN))
- {
- if(parse_track_gpx(buffer, size, -1))
- {
- map_force_redraw();
- hildon_banner_show_information(_window, NULL, _("Track Opened"));
- }
- else
- popup_error(_window, _("Error parsing GPX file."));
- g_free(buffer);
- }
-
- vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
- return TRUE;
-}
-
-#define WRITE_STRING(string) { \
- GnomeVFSResult vfs_result; \
- GnomeVFSFileSize size; \
- if(GNOME_VFS_OK != (vfs_result = gnome_vfs_write( \
- handle, (string), strlen((string)), &size))) \
- { \
- gchar buffer[1024]; \
- sprintf(buffer, "%s:\n%s\n%s", _("Error while writing to file"), \
- _("File is incomplete."), \
- gnome_vfs_result_to_string(vfs_result)); \
- popup_error(_window, buffer); \
- return FALSE; \
- } \
-}
-
-static gboolean
-write_track_gpx(GnomeVFSHandle *handle)
-{
- TrackPoint *curr;
- gboolean trkseg_break = FALSE;
- printf("%s()\n", __PRETTY_FUNCTION__);
-
- /* Find first non-zero point. */
- for(curr = _track.head-1; curr++ != _track.tail; )
- if(curr->point.unity)
- break;
-
- /* Write the header. */
- WRITE_STRING(XML_TRKSEG_HEADER);
-
- /* Curr points to first non-zero point. */
- for(curr--; curr++ != _track.tail; )
- {
- gfloat lat, lon;
- if(curr->point.unity)
- {
- gchar buffer[80];
- gchar strlat[80], strlon[80];
- if(trkseg_break)
- {
- /* First trkpt of the segment - write trkseg header. */
- WRITE_STRING(" </trkseg>\n"
- /* Write trkseg header. */
- " <trkseg>\n");
- trkseg_break = FALSE;
- }
- unit2latlon(curr->point.unitx, curr->point.unity, lat, lon);
- g_ascii_formatd(strlat, 80, "%.06f", lat);
- g_ascii_formatd(strlon, 80, "%.06f", lon);
- sprintf(buffer, " <trkpt lat=\"%s\" lon=\"%s\"",
- strlat, strlon);
- WRITE_STRING(buffer);
+ GTK_FILE_CHOOSER_ACTION_OPEN))
+ {
+ /* If auto is enabled, append the route, otherwise replace it. */
+ if(parse_route_gpx(buffer, size, _autoroute_data.enabled ? 0 : 1))
+ {
+ cancel_autoroute();
- /* write the time */
- if(curr->time)
- {
- WRITE_STRING(">\n <time>");
- {
- struct tm time;
- localtime_r(&curr->time, &time);
- strftime(buffer, 80, XML_DATE_FORMAT, &time);
- WRITE_STRING(buffer);
- WRITE_STRING(XML_TZONE);
- }
- WRITE_STRING("</time>\n"
- " </trkpt>\n");
- }
- else
- WRITE_STRING("/>\n");
+ /* Find the nearest route point, if we're connected. */
+ route_find_nearest_point();
+
+ map_force_redraw();
+ hildon_banner_show_information(_window, NULL,
+ _("Route Opened"));
}
else
- trkseg_break = TRUE;
+ popup_error(_window, _("Error parsing GPX file."));
+ g_free(buffer);
}
- /* Write the footer. */
- WRITE_STRING(XML_TRKSEG_FOOTER);
+ vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+ return TRUE;
+}
+
+static gboolean
+menu_cb_route_reset(GtkAction *action)
+{
+ printf("%s()\n", __PRETTY_FUNCTION__);
+
+ if(_route.head)
+ {
+ route_find_nearest_point();
+ map_render_paths();
+ map_render_poi();
+ MACRO_QUEUE_DRAW_AREA();
+ }
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
return TRUE;
}
static gboolean
-write_route_gpx(GnomeVFSHandle *handle)
+menu_cb_route_clear(GtkAction *action)
{
- Point *curr;
- WayPoint *wcurr;
- gboolean trkseg_break = FALSE;
+ printf("%s()\n", __PRETTY_FUNCTION__);
- /* Find first non-zero point. */
- for(curr = _route.head-1, wcurr = _route.whead; curr++ != _route.tail; )
- if(curr->unity)
- break;
- else if(curr == wcurr->point)
- wcurr++;
+ _next_way_dist_rough = -1; /* to avoid announcement attempts. */
+ cancel_autoroute();
+ MACRO_CLEAR_TRACK(_route);
+ map_force_redraw();
- /* Write the header. */
- WRITE_STRING(XML_TRKSEG_HEADER);
+ vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+ return TRUE;
+}
- /* Curr points to first non-zero point. */
- for(curr--; curr++ != _route.tail; )
+static gboolean
+menu_cb_track_open(GtkAction *action)
+{
+ gchar *buffer;
+ gint size;
+ printf("%s()\n", __PRETTY_FUNCTION__);
+
+ if(open_file(&buffer, NULL, &size, NULL, &_track_file_uri,
+ GTK_FILE_CHOOSER_ACTION_OPEN))
{
- gfloat lat, lon;
- if(curr->unity)
+ if(parse_track_gpx(buffer, size, -1))
{
- gchar buffer[80];
- gchar strlat[80], strlon[80];
- if(trkseg_break)
- {
- /* First trkpt of the segment - write trkseg header. */
- WRITE_STRING(" </trkseg>\n"
- " <trkseg>\n");
- trkseg_break = FALSE;
- }
- unit2latlon(curr->unitx, curr->unity, lat, lon);
- g_ascii_formatd(strlat, 80, "%.06f", lat);
- g_ascii_formatd(strlon, 80, "%.06f", lon);
- sprintf(buffer, " <trkpt lat=\"%s\" lon=\"%s\"",
- strlat, strlon);
- if(curr == wcurr->point)
- sprintf(buffer + strlen(buffer),
- "><desc>%s</desc></trkpt>\n", wcurr++->desc);
- else
- strcat(buffer, "/>\n");
- WRITE_STRING(buffer);
+ map_force_redraw();
+ hildon_banner_show_information(_window, NULL, _("Track Opened"));
}
else
- trkseg_break = TRUE;
+ popup_error(_window, _("Error parsing GPX file."));
+ g_free(buffer);
}
- /* Write the footer. */
- WRITE_STRING(XML_TRKSEG_FOOTER);
-
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
return TRUE;
}
typedef struct _MapmanInfo MapmanInfo;
struct _MapmanInfo {
+ GtkWidget *dialog;
GtkWidget *notebook;
GtkWidget *tbl_area;
GtkWidget *rad_delete;
GtkWidget *chk_overwrite;
GtkWidget *rad_by_area;
- GtkWidget *rad_along_route;
- GtkWidget *txt_route_radius;
+ GtkWidget *rad_by_route;
+ GtkWidget *num_route_radius;
/* The "Area" tab. */
GtkWidget *txt_topleft_lat;
GtkWidget *chk_zoom_levels[MAX_ZOOM];
};
+static gboolean
+mapman_by_area(gfloat start_lat, gfloat start_lon,
+ gfloat end_lat, gfloat end_lon, MapmanInfo *mapman_info,
+ gboolean is_deleting, gboolean is_overwriting)
+{
+ guint start_unitx, start_unity, end_unitx, end_unity;
+ guint num_maps = 0;
+ guint i;
+ gchar buffer[80];
+ GtkWidget *confirm;
+ printf("%s()\n", __PRETTY_FUNCTION__);
+
+ latlon2unit(start_lat, start_lon, start_unitx, start_unity);
+ latlon2unit(end_lat, end_lon, end_unitx, end_unity);
+
+ /* Swap if they specified flipped lats or lons. */
+ if(start_unitx > end_unitx)
+ {
+ guint swap = start_unitx;
+ start_unitx = end_unitx;
+ end_unitx = swap;
+ }
+ if(start_unity > end_unity)
+ {
+ guint swap = start_unity;
+ start_unity = end_unity;
+ end_unity = swap;
+ }
+
+ /* First, get the number of maps to download. */
+ for(i = 0; i < MAX_ZOOM; i++)
+ {
+ if(gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[i])))
+ {
+ guint start_tilex, start_tiley, end_tilex, end_tiley;
+ start_tilex = unit2ztile(start_unitx, i);
+ start_tiley = unit2ztile(start_unity, i);
+ end_tilex = unit2ztile(end_unitx, i);
+ end_tiley = unit2ztile(end_unity, i);
+ num_maps += (end_tilex - start_tilex + 1)
+ * (end_tiley - start_tiley + 1);
+ }
+ }
+
+ if(is_deleting)
+ {
+ sprintf(buffer, "%s %d %s", _("Confirm DELETION of"),
+ num_maps, _("maps"));
+ }
+ else
+ {
+ sprintf(buffer,
+ "%s %d %s\n(%s %.2f MB)\n", _("Confirm download of"),
+ num_maps, _("maps"), _("up to about"),
+ num_maps * (strstr(_curr_repo->url, "%s") ? 18e-3 : 6e-3));
+ }
+ confirm = hildon_note_new_confirmation(
+ GTK_WINDOW(mapman_info->dialog), buffer);
+
+ if(GTK_RESPONSE_OK != gtk_dialog_run(GTK_DIALOG(confirm)))
+ {
+ gtk_widget_destroy(confirm);
+ vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+ return FALSE;
+ }
+ for(i = 0; i < MAX_ZOOM; i++)
+ {
+ if(gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[i])))
+ {
+ guint start_tilex, start_tiley, end_tilex, end_tiley;
+ guint tilex, tiley;
+ start_tilex = unit2ztile(start_unitx, i);
+ start_tiley = unit2ztile(start_unity, i);
+ end_tilex = unit2ztile(end_unitx, i);
+ end_tiley = unit2ztile(end_unity, i);
+ for(tiley = start_tiley; tiley <= end_tiley; tiley++)
+ for(tilex = start_tilex; tilex <= end_tilex; tilex++)
+ map_initiate_download(tilex, tiley, i,
+ is_deleting ? 0 :
+ (is_overwriting
+ ? -INITIAL_DOWNLOAD_RETRIES
+ : INITIAL_DOWNLOAD_RETRIES));
+ }
+ }
+ gtk_widget_destroy(confirm);
+ vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+ return TRUE;
+}
+
+static gboolean
+mapman_by_route(MapmanInfo *mapman_info,
+ gboolean is_deleting, gboolean is_overwriting)
+{
+ GtkWidget *confirm;
+ guint prev_tilex, prev_tiley, num_maps = 0, i;
+ Point *curr;
+ gchar buffer[80];
+ guint radius = hildon_number_editor_get_value(
+ HILDON_NUMBER_EDITOR(mapman_info->num_route_radius));
+ printf("%s()\n", __PRETTY_FUNCTION__);
+
+ if(!_route.head)
+ {
+ popup_error(mapman_info->dialog, "No route is loaded.");
+ return TRUE;
+ }
+
+ /* First, get the number of maps to download. */
+ for(i = 0; i < MAX_ZOOM; i++)
+ {
+ if(gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[i])))
+ {
+ prev_tilex = 0;
+ prev_tiley = 0;
+ for(curr = _route.head - 1; ++curr != _route.tail; )
+ {
+ if(curr->unity)
+ {
+ guint tilex = unit2ztile(curr->unitx, i);
+ guint tiley = unit2ztile(curr->unity, i);
+ if(tilex != prev_tilex || tiley != prev_tiley)
+ {
+ if(prev_tiley)
+ num_maps += (abs((gint)tilex - prev_tilex) + 1)
+ * (abs((gint)tiley - prev_tiley) + 1) - 1;
+ prev_tilex = tilex;
+ prev_tiley = tiley;
+ }
+ }
+ }
+ }
+ }
+ num_maps *= 0.625 * pow(radius + 1, 1.85);
+
+ if(is_deleting)
+ {
+ sprintf(buffer, "%s %s %d %s", _("Confirm DELETION of"), _("about"),
+ num_maps, _("maps"));
+ }
+ else
+ {
+ sprintf(buffer,
+ "%s %s %d %s\n(%s %.2f MB)\n", _("Confirm download of"),
+ _("about"),
+ num_maps, _("maps"), _("up to about"),
+ num_maps * (strstr(_curr_repo->url, "%s") ? 18e-3 : 6e-3));
+ }
+ confirm = hildon_note_new_confirmation(
+ GTK_WINDOW(mapman_info->dialog), buffer);
+
+ if(GTK_RESPONSE_OK != gtk_dialog_run(GTK_DIALOG(confirm)))
+ {
+ gtk_widget_destroy(confirm);
+ vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
+ return FALSE;
+ }
+
+ /* Now, do the actual download. */
+ for(i = 0; i < MAX_ZOOM; i++)
+ {
+ if(gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[i])))
+ {
+ prev_tilex = 0;
+ prev_tiley = 0;
+ for(curr = _route.head - 1; ++curr != _route.tail; )
+ {
+ if(curr->unity)
+ {
+ guint tilex = unit2ztile(curr->unitx, i);
+ guint tiley = unit2ztile(curr->unity, i);
+ if(tilex != prev_tilex || tiley != prev_tiley)
+ {
+ guint minx, miny, maxx, maxy, x, y;
+ if(prev_tiley != 0)
+ {
+ minx = MIN(tilex, prev_tilex) - radius;
+ miny = MIN(tiley, prev_tiley) - radius;
+ maxx = MAX(tilex, prev_tilex) + radius;
+ maxy = MAX(tiley, prev_tiley) + radius;
+ }
+ else
+ {
+ minx = tilex - radius;
+ miny = tiley - radius;
+ maxx = tilex + radius;
+ maxy = tiley + radius;
+ }
+ for(x = minx; x <= maxx; x++)
+ for(y = miny; y <= maxy; y++)
+ map_initiate_download(x, y, i,
+ is_deleting ? 0 :
+ (is_overwriting
+ ? -INITIAL_DOWNLOAD_RETRIES
+ : INITIAL_DOWNLOAD_RETRIES));
+ prev_tilex = tilex;
+ prev_tiley = tiley;
+ }
+ }
+ }
+ }
+ }
+ _route_dl_radius = radius;
+ gtk_widget_destroy(confirm);
+ vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
+ return TRUE;
+}
+
static void mapman_clear(GtkWidget *widget, MapmanInfo *mapman_info)
{
guint i;
else if(gtk_notebook_get_n_pages(GTK_NOTEBOOK(mapman_info->notebook)) == 3)
gtk_widget_hide(mapman_info->tbl_area);
- gtk_widget_set_sensitive(mapman_info->txt_route_radius,
+ gtk_widget_set_sensitive(mapman_info->num_route_radius,
gtk_toggle_button_get_active(
- GTK_TOGGLE_BUTTON(mapman_info->rad_along_route)));
+ GTK_TOGGLE_BUTTON(mapman_info->rad_by_route)));
}
static gboolean
guint i;
printf("%s()\n", __PRETTY_FUNCTION__);
- dialog = gtk_dialog_new_with_buttons(_("Manage Maps"),
+ mapman_info.dialog = dialog = gtk_dialog_new_with_buttons(_("Manage Maps"),
GTK_WINDOW(_window), GTK_DIALOG_MODAL,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
NULL);
hbox = gtk_hbox_new(FALSE, 4),
FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(hbox),
- mapman_info.rad_along_route
+ mapman_info.rad_by_route
= gtk_radio_button_new_with_label_from_widget(
GTK_RADIO_BUTTON(mapman_info.rad_by_area),
- _("Along Route - Radius:")),
+ _("Along Route - Radius (tiles):")),
FALSE, FALSE, 0);
- gtk_widget_set_sensitive(mapman_info.rad_along_route, _route.head != NULL);
+ gtk_widget_set_sensitive(mapman_info.rad_by_route, _route.head != NULL);
gtk_box_pack_start(GTK_BOX(hbox),
- mapman_info.txt_route_radius
- = gtk_entry_new(),
+ mapman_info.num_route_radius = hildon_number_editor_new(0, 100),
FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(hbox),
- gtk_label_new(UNITS_TEXT[_units]), FALSE, FALSE, 0);
- gtk_entry_set_alignment(GTK_ENTRY(mapman_info.txt_route_radius), 1.f);
+ hildon_number_editor_set_value(
+ HILDON_NUMBER_EDITOR(mapman_info.num_route_radius),
+ _route_dl_radius);
/* Zoom page. */
G_CALLBACK(mapman_update_state), &mapman_info);
g_signal_connect(G_OBJECT(mapman_info.rad_by_area), "clicked",
G_CALLBACK(mapman_update_state), &mapman_info);
- g_signal_connect(G_OBJECT(mapman_info.rad_along_route), "clicked",
+ g_signal_connect(G_OBJECT(mapman_info.rad_by_route), "clicked",
G_CALLBACK(mapman_update_state), &mapman_info);
while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
{
- const gchar *text;
- gchar *error_check;
- gfloat start_lat, start_lon, end_lat, end_lon;
- guint start_unitx, start_unity, end_unitx, end_unity;
- guint num_maps = 0;
- GtkWidget *confirm;
- gboolean is_deleting, is_overwriting;
-
- text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_topleft_lat));
- start_lat = strtof(text, &error_check);
- if(text == error_check) {
- popup_error(dialog, _("Invalid Top-Left Latitude"));
- continue;
- }
-
- text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_topleft_lon));
- start_lon = strtof(text, &error_check);
- if(text == error_check) {
- popup_error(dialog, _("Invalid Top-Left Longitude"));
- continue;
- }
-
- text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_botright_lat));
- end_lat = strtof(text, &error_check);
- if(text == error_check) {
- popup_error(dialog, _("Invalid Bottom-Right Latitude"));
- continue;
- }
-
- text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_botright_lon));
- end_lon = strtof(text, &error_check);
- if(text == error_check) {
- popup_error(dialog,_("Invalid Bottom-Right Longitude"));
- continue;
- }
-
- latlon2unit(start_lat, start_lon, start_unitx, start_unity);
- latlon2unit(end_lat, end_lon, end_unitx, end_unity);
-
- /* Swap if they specified flipped lats or lons. */
- if(start_unitx > end_unitx)
- {
- guint swap = start_unitx;
- start_unitx = end_unitx;
- end_unitx = swap;
- }
- if(start_unity > end_unity)
- {
- guint swap = start_unity;
- start_unity = end_unity;
- end_unity = swap;
- }
-
- /* First, get the number of maps to download. */
- for(i = 0; i < MAX_ZOOM; i++)
- {
- if(gtk_toggle_button_get_active(
- GTK_TOGGLE_BUTTON(mapman_info.chk_zoom_levels[i])))
- {
- guint start_tilex, start_tiley, end_tilex, end_tiley;
- start_tilex = unit2ztile(start_unitx, i);
- start_tiley = unit2ztile(start_unity, i);
- end_tilex = unit2ztile(end_unitx, i);
- end_tiley = unit2ztile(end_unity, i);
- num_maps += (end_tilex - start_tilex + 1)
- * (end_tiley - start_tiley + 1);
- }
- }
- text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_topleft_lat));
-
- is_deleting = gtk_toggle_button_get_active(
+ gboolean is_deleting = gtk_toggle_button_get_active(
GTK_TOGGLE_BUTTON(mapman_info.rad_delete));
- is_overwriting = gtk_toggle_button_get_active(
+ gboolean is_overwriting = gtk_toggle_button_get_active(
GTK_TOGGLE_BUTTON(mapman_info.chk_overwrite));
-
- if(is_deleting)
+ if(gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON(mapman_info.rad_by_route)))
{
- sprintf(buffer, "%s %d %s", _("Confirm DELETION of"),
- num_maps, _("maps"));
+ if(mapman_by_route(&mapman_info, is_deleting, is_overwriting))
+ break;
}
else
{
- sprintf(buffer,
- "%s %d %s\n(%s %.2f MB)\n", _("Confirm download of"),
- num_maps, _("maps"), _("up to about"),
- num_maps * (strstr(_curr_repo->url, "%s") ? 18e-3 : 6e-3));
- }
- text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_topleft_lat));
- confirm = hildon_note_new_confirmation(GTK_WINDOW(dialog), buffer);
- text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_topleft_lat));
+ const gchar *text;
+ gchar *error_check;
+ gfloat start_lat, start_lon, end_lat, end_lon;
+
+ text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_topleft_lat));
+ start_lat = strtof(text, &error_check);
+ if(text == error_check) {
+ popup_error(dialog, _("Invalid Top-Left Latitude"));
+ continue;
+ }
- if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
- {
- for(i = 0; i < MAX_ZOOM; i++)
- {
- if(gtk_toggle_button_get_active(
- GTK_TOGGLE_BUTTON(mapman_info.chk_zoom_levels[i])))
- {
- guint start_tilex, start_tiley, end_tilex, end_tiley;
- guint tilex, tiley;
- start_tilex = unit2ztile(start_unitx, i);
- start_tiley = unit2ztile(start_unity, i);
- end_tilex = unit2ztile(end_unitx, i);
- end_tiley = unit2ztile(end_unity, i);
- for(tiley = start_tiley; tiley <= end_tiley; tiley++)
- for(tilex = start_tilex; tilex <= end_tilex; tilex++)
- map_initiate_download(tilex, tiley, i,
- is_deleting ? 0 :
- (is_overwriting
- ? -INITIAL_DOWNLOAD_RETRIES
- : INITIAL_DOWNLOAD_RETRIES));
- }
+ text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_topleft_lon));
+ start_lon = strtof(text, &error_check);
+ if(text == error_check) {
+ popup_error(dialog, _("Invalid Top-Left Longitude"));
+ continue;
}
- gtk_widget_destroy(confirm);
- break;
+
+ text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_botright_lat));
+ end_lat = strtof(text, &error_check);
+ if(text == error_check) {
+ popup_error(dialog, _("Invalid Bottom-Right Latitude"));
+ continue;
+ }
+
+ text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_botright_lon));
+ end_lon = strtof(text, &error_check);
+ if(text == error_check) {
+ popup_error(dialog,_("Invalid Bottom-Right Longitude"));
+ continue;
+ }
+
+ if(mapman_by_area(start_lat, start_lon, end_lat, end_lon,
+ &mapman_info, is_deleting, is_overwriting))
+ break;
}
- gtk_widget_destroy(confirm);
}
gtk_widget_hide(dialog); /* Destroying causes a crash (!?!?!??!) */