Contents of /trunk/src/map-tool.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 40 - (show annotations)
Sun Aug 2 19:05:24 2009 UTC (14 years, 9 months ago) by harbaum
File MIME type: text/plain
File size: 7672 byte(s)
Map via stackable window in fremantle
1 /*
2 * Copyright (C) 2008 Till Harbaum <till@harbaum.org>.
3 *
4 * This file is part of GPXView.
5 *
6 * GPXView is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * GPXView is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GPXView. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "gpxview.h"
21 #include <math.h> // for isnan
22
23 #ifdef ENABLE_OSM_GPS_MAP
24 #include "osm-gps-map.h"
25 #endif
26
27 typedef struct {
28 appdata_t *appdata;
29 GtkWidget *widget;
30 GtkWidget *zoomin, *zoomout, *gps;
31 gint handler_id;
32 #if MAEMO_VERSION_MAJOR == 5
33 GtkWidget *old_view;
34 #endif
35 } map_context_t;
36
37 #define PROXY_KEY "/system/http_proxy/"
38
39 static const char *get_proxy_uri(appdata_t *appdata) {
40 static char proxy_buffer[64] = "";
41
42 /* use environment settings if preset */
43 const char *proxy = g_getenv("http_proxy");
44 if(proxy) {
45 printf("http_proxy: %s\n", proxy);
46 return proxy;
47 }
48
49 /* ------------- get proxy settings -------------------- */
50 if(gconf_client_get_bool(appdata->gconf_client,
51 PROXY_KEY "use_http_proxy", NULL)) {
52
53 /* we can savely ignore things like "ignore_hosts" since we */
54 /* are pretty sure not inside the net of one of our map renderers */
55 /* (unless the user works at google :-) */
56
57 /* get basic settings */
58 char *host =
59 gconf_client_get_string(appdata->gconf_client, PROXY_KEY "host", NULL);
60 if(host) {
61 int port =
62 gconf_client_get_int(appdata->gconf_client, PROXY_KEY "port", NULL);
63
64 snprintf(proxy_buffer, sizeof(proxy_buffer),
65 "http://%s:%u", host, port);
66
67 g_free(host);
68 }
69 return proxy_buffer;
70 }
71
72 return NULL;
73 }
74
75 static void map_zoom(map_context_t *context, int step) {
76 int zoom;
77 OsmGpsMap *map = OSM_GPS_MAP(context->widget);
78 g_object_get(map, "zoom", &zoom, NULL);
79 zoom = osm_gps_map_set_zoom(map, zoom+step);
80
81 /* enable/disable zoom buttons as required */
82 gtk_widget_set_sensitive(context->zoomin, zoom<17);
83 gtk_widget_set_sensitive(context->zoomout, zoom>1);
84 }
85
86 static gboolean
87 cb_map_zoomin(GtkButton *button, map_context_t *context) {
88 map_zoom(context, +1);
89 return FALSE;
90 }
91
92 static gboolean
93 cb_map_zoomout(GtkButton *button, map_context_t *context) {
94 map_zoom(context, -1);
95 return FALSE;
96 }
97
98 static gboolean
99 cb_map_gps(GtkButton *button, map_context_t *context) {
100 pos_t *refpos = get_pos(context->appdata);
101 if(refpos && !isnan(refpos->lat) && !isnan(refpos->lon)) {
102 osm_gps_map_set_mapcenter(OSM_GPS_MAP(context->widget),
103 refpos->lat, refpos->lon, 14);
104 } else {
105 /* no coordinates given: display the entire world */
106 osm_gps_map_set_mapcenter(OSM_GPS_MAP(context->widget),
107 0.0, 0.0, 1);
108 }
109
110 return FALSE;
111 }
112
113 static GtkWidget
114 *map_add_button(const gchar *icon, GCallback cb, gpointer data,
115 char *tooltip) {
116 GtkWidget *button = gtk_button_new();
117 gtk_button_set_image(GTK_BUTTON(button),
118 gtk_image_new_from_stock(icon, GTK_ICON_SIZE_MENU));
119 g_signal_connect(button, "clicked", cb, data);
120 #ifndef USE_MAEMO
121 gtk_widget_set_tooltip_text(button, tooltip);
122 #endif
123 return button;
124 }
125
126 static gboolean map_gps_update(gpointer data) {
127 map_context_t *context = (map_context_t*)data;
128
129 pos_t *refpos = get_pos(context->appdata);
130 gboolean ok = (refpos!= NULL) && !isnan(refpos->lat) && !isnan(refpos->lon);
131
132 /* get reference position and go there */
133 gtk_widget_set_sensitive(context->gps, ok);
134
135 return TRUE;
136 }
137
138 static gboolean on_map_configure(GtkWidget *widget,
139 GdkEventConfigure *event,
140 map_context_t *context) {
141
142 cb_map_gps(NULL, context);
143
144 return FALSE;
145 }
146
147 static void map_draw_cachelist(GtkWidget *map, cache_t *cache) {
148 while(cache) {
149 GdkPixbuf *icon = icon_get(ICON_CACHE_TYPE, cache->type);
150
151 osm_gps_map_add_image(OSM_GPS_MAP(map),
152 cache->pos.lat, cache->pos.lon, icon);
153
154 cache = cache->next;
155 }
156 }
157
158 #if MAEMO_VERSION_MAJOR == 5
159 static void on_window_destroy(GtkWidget *widget, map_context_t *context) {
160 printf("destroy map view\n");
161
162 /* restore cur_view */
163 context->appdata->cur_view = context->old_view;
164
165 gtk_timeout_remove(context->handler_id);
166 g_free(context);
167 }
168 #endif
169
170 void map(appdata_t *appdata) {
171 map_context_t *context = g_new0(map_context_t, 1);
172 context->appdata = appdata;
173
174 #if MAEMO_VERSION_MAJOR == 5
175 GtkWidget *window = hildon_stackable_window_new();
176 gtk_window_set_title(GTK_WINDOW(window), _("Map"));
177 #else
178 GtkWidget *dialog = gtk_dialog_new_with_buttons(_("Map"),
179 GTK_WINDOW(appdata->window),
180 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
181 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
182 NULL);
183
184 #ifndef USE_MAEMO
185 gtk_window_set_default_size(GTK_WINDOW(dialog), 400, 350);
186 #else
187 gtk_window_set_default_size(GTK_WINDOW(dialog), 800, 480);
188 #endif
189 #endif
190
191 GtkWidget *hbox = gtk_hbox_new(FALSE, 0);
192
193 char *path = g_strdup_printf("%s/map/", appdata->image_path);
194 const char *proxy = get_proxy_uri(appdata);
195
196 context->widget = g_object_new(OSM_TYPE_GPS_MAP,
197 "repo-uri", MAP_SOURCE_OPENSTREETMAP,
198 "tile-cache", path,
199 proxy?"proxy-uri":NULL, proxy,
200 NULL);
201
202 g_free(path);
203
204 /* draw all geocaches */
205 gpx_t *gpx = appdata->gpx;
206 while(gpx) {
207 map_draw_cachelist(context->widget, gpx->cache);
208 gpx = gpx->next;
209 }
210
211 g_signal_connect(G_OBJECT(context->widget), "configure-event",
212 G_CALLBACK(on_map_configure), context);
213 #if 0
214 g_signal_connect(G_OBJECT(context->widget), "button-release-event",
215 G_CALLBACK(on_map_button_release_event), context);
216 #endif
217
218 gtk_box_pack_start_defaults(GTK_BOX(hbox), context->widget);
219 /* zoom button box */
220 GtkWidget *vbox = gtk_vbox_new(FALSE,0);
221
222 context->zoomin =
223 map_add_button(GTK_STOCK_ZOOM_IN, G_CALLBACK(cb_map_zoomin),
224 context, _("Zoom in"));
225 gtk_box_pack_start(GTK_BOX(vbox), context->zoomin, FALSE, FALSE, 0);
226
227 context->zoomout =
228 map_add_button(GTK_STOCK_ZOOM_OUT, G_CALLBACK(cb_map_zoomout),
229 context, _("Zoom out"));
230 gtk_box_pack_start(GTK_BOX(vbox), context->zoomout, FALSE, FALSE, 0);
231
232 context->gps =
233 map_add_button(GTK_STOCK_HOME, G_CALLBACK(cb_map_gps),
234 context, _("Jump to GPS position"));
235 gtk_widget_set_sensitive(context->gps, FALSE);
236 /* install handler for timed updates of the gps button */
237 context->handler_id = gtk_timeout_add(1000, map_gps_update, context);
238 gtk_box_pack_start(GTK_BOX(vbox), context->gps, FALSE, FALSE, 0);
239
240 gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
241
242 #if MAEMO_VERSION_MAJOR == 5
243 /* prevent some of the main screen things */
244 context->old_view = appdata->cur_view;
245 appdata->cur_view = NULL;
246
247 g_signal_connect(G_OBJECT(window), "destroy",
248 G_CALLBACK(on_window_destroy), context);
249
250 gtk_container_add(GTK_CONTAINER(window), hbox);
251 gtk_widget_show_all(GTK_WIDGET(window));
252
253 #else
254 gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox);
255 gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CLOSE);
256 gtk_widget_show_all(dialog);
257 gtk_dialog_run(GTK_DIALOG(dialog));
258 gtk_timeout_remove(context->handler_id);
259 gtk_widget_destroy(dialog);
260 g_free(context);
261 #endif
262 }