Contents of /trunk/src/main.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 24 - (hide annotations)
Sun Dec 21 11:49:35 2008 UTC (15 years, 5 months ago) by harbaum
File MIME type: text/plain
File size: 24981 byte(s)
Option to disable antialiasing
1 harbaum 1 /*
2     * This file is part of OSM2Go.
3     *
4     * OSM2Go is free software: you can redistribute it and/or modify
5     * it under the terms of the GNU General Public License as published by
6     * the Free Software Foundation, either version 3 of the License, or
7     * (at your option) any later version.
8     *
9     * OSM2Go is distributed in the hope that it will be useful,
10     * but WITHOUT ANY WARRANTY; without even the implied warranty of
11     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12     * GNU General Public License for more details.
13     *
14     * You should have received a copy of the GNU General Public License
15     * along with OSM2Go. If not, see <http://www.gnu.org/licenses/>.
16     */
17    
18     #include <stdio.h>
19     #include <string.h>
20    
21     #include <curl/curl.h>
22 harbaum 22 #include <gdk/gdkkeysyms.h>
23 harbaum 1
24     #include "appdata.h"
25    
26     /* disable/enable main screen control dependant on presence of open project */
27 harbaum 4 static void main_ui_enable(appdata_t *appdata) {
28     gboolean project_valid = (appdata->project != NULL);
29     gboolean osm_valid = (appdata->osm != NULL);
30 harbaum 1
31     /* cancel any action in progress */
32     if(GTK_WIDGET_FLAGS(appdata->iconbar->cancel) & GTK_SENSITIVE)
33     map_action_cancel(appdata);
34    
35     /* ---- set project name as window title ----- */
36     #ifndef USE_HILDON
37     char *str = NULL;
38 harbaum 4 if(project_valid)
39 harbaum 1 str = g_strdup_printf("OSM2Go - %s", appdata->project->name);
40     else
41     str = g_strdup_printf("OSM2Go");
42    
43     gtk_window_set_title(GTK_WINDOW(appdata->window), str);
44     g_free(str);
45     #else
46 harbaum 4 if(project_valid)
47 harbaum 1 gtk_window_set_title(GTK_WINDOW(appdata->window), appdata->project->name);
48     else
49     gtk_window_set_title(GTK_WINDOW(appdata->window), "");
50     #endif
51    
52     if(appdata->iconbar && appdata->iconbar->toolbar)
53 harbaum 4 gtk_widget_set_sensitive(appdata->iconbar->toolbar, osm_valid);
54 harbaum 1
55     /* disable all menu entries related to map */
56 harbaum 4 gtk_widget_set_sensitive(appdata->menu_osm, project_valid);
57     gtk_widget_set_sensitive(appdata->menu_item_osm_upload, osm_valid);
58     gtk_widget_set_sensitive(appdata->menu_item_osm_diff, osm_valid);
59 harbaum 15 gtk_widget_set_sensitive(appdata->menu_item_osm_undo_changes, osm_valid);
60 harbaum 4 gtk_widget_set_sensitive(appdata->track.menu_track, osm_valid);
61     gtk_widget_set_sensitive(appdata->menu_view, osm_valid);
62     gtk_widget_set_sensitive(appdata->menu_wms, osm_valid);
63     gtk_widget_set_sensitive(appdata->menu_map, osm_valid);
64     gtk_widget_set_sensitive(appdata->menu_item_project_close, project_valid);
65 harbaum 1
66 harbaum 4 if(!project_valid)
67 achadwick 6 statusbar_set(appdata, _("Please load or create a project"), FALSE);
68 harbaum 1 }
69    
70     /******************** begin of menu *********************/
71    
72     #if 0 // simplify menu
73     static struct {
74     enum { MENU_END, MENU_ITEM, MENU_SUB, MENU_SUB_END, MENU_SEP } type;
75    
76     char *title;
77     GCallback c_handler;
78     } menu[] = {
79 harbaum 22 { MENU_SUB, "_OSM", NULL },
80    
81 harbaum 1 { MENU_END, NULL, NULL },
82     };
83     #endif
84    
85     static void
86     cb_menu_project_open(GtkWidget *window, gpointer data) {
87     appdata_t *appdata = (appdata_t*)data;
88     project_load(appdata, NULL);
89 harbaum 4 main_ui_enable(appdata);
90 harbaum 1 }
91    
92     static void
93     cb_menu_project_close(GtkWidget *window, gpointer data) {
94     appdata_t *appdata = (appdata_t*)data;
95     project_close(appdata);
96 harbaum 4 main_ui_enable(appdata);
97 harbaum 1 }
98    
99     static void
100     cb_menu_about(GtkWidget *window, gpointer data) {
101     GtkAboutDialog *about = GTK_ABOUT_DIALOG(gtk_about_dialog_new());
102    
103     gtk_about_dialog_set_name(about, "OSM2Go");
104     gtk_about_dialog_set_version(about, VERSION);
105     gtk_about_dialog_set_copyright(about, _("Copyright 2008"));
106    
107     const gchar *authors[] = {
108     "Till Harbaum <till@harbaum.org>",
109     "Andrew Chadwick",
110     NULL };
111    
112     gtk_about_dialog_set_authors(about, authors);
113    
114     gtk_about_dialog_set_website(about,
115     _("http://www.harbaum.org/till/maemo"));
116    
117     gtk_about_dialog_set_comments(about,
118     _("Mobile OSM Editor"));
119    
120     gtk_widget_show_all(GTK_WIDGET(about));
121     gtk_dialog_run(GTK_DIALOG(about));
122     gtk_widget_destroy(GTK_WIDGET(about));
123     }
124    
125     void on_window_destroy (GtkWidget *widget, gpointer data);
126    
127     static void
128     cb_menu_quit(GtkWidget *window, gpointer data) {
129     appdata_t *appdata = (appdata_t*)data;
130     gtk_widget_destroy(GTK_WIDGET(appdata->window));
131     }
132    
133     static void
134     cb_menu_upload(GtkWidget *window, gpointer data) {
135     appdata_t *appdata = (appdata_t*)data;
136     if(!appdata->osm || !appdata->project) return;
137    
138     osm_upload(appdata, appdata->osm, appdata->project);
139     }
140    
141     static void
142     cb_menu_download(GtkWidget *window, gpointer data) {
143     appdata_t *appdata = (appdata_t*)data;
144 harbaum 4 if(!appdata->project) return;
145 harbaum 1
146 harbaum 4 /* if we have valid osm data loaded: save state first */
147     if(appdata->osm) {
148     /* redraw the entire map by destroying all map items and redrawing them */
149     diff_save(appdata->project, appdata->osm);
150     map_clear(appdata, MAP_LAYER_OBJECTS_ONLY);
151     osm_free(&appdata->icon, appdata->osm);
152 harbaum 1
153 harbaum 4 appdata->osm = NULL;
154     }
155    
156 harbaum 1 // download
157 harbaum 4 if(osm_download(GTK_WIDGET(appdata->window), appdata->project)) {
158     appdata->osm = osm_parse(appdata->project->osm);
159     diff_restore(appdata, appdata->project, appdata->osm);
160     map_paint(appdata);
161     }
162 harbaum 1
163 harbaum 4 main_ui_enable(appdata);
164 harbaum 1 }
165    
166     static void
167     cb_menu_wms_import(GtkWidget *window, gpointer data) {
168     appdata_t *appdata = (appdata_t*)data;
169     wms_import(appdata);
170     }
171    
172     static void
173     cb_menu_wms_clear(GtkWidget *window, gpointer data) {
174     appdata_t *appdata = (appdata_t*)data;
175     wms_remove(appdata);
176     }
177    
178     static void
179     cb_menu_wms_adjust(GtkWidget *window, gpointer data) {
180     appdata_t *appdata = (appdata_t*)data;
181     map_action_set(appdata, MAP_ACTION_BG_ADJUST);
182     }
183    
184     /* ----------- hide objects for performance reasons ----------- */
185    
186     static void
187     cb_menu_map_hide_sel(GtkWidget *window, gpointer data) {
188     appdata_t *appdata = (appdata_t*)data;
189     map_hide_selected(appdata);
190     }
191    
192     static void
193     cb_menu_map_show_all(GtkWidget *window, gpointer data) {
194     appdata_t *appdata = (appdata_t*)data;
195     map_show_all(appdata);
196     }
197    
198 harbaum 14 /* ---------------------------------------------------------- */
199 harbaum 1
200     #if 1 // mainly for testing
201     static void
202     cb_menu_redraw(GtkWidget *window, gpointer data) {
203     appdata_t *appdata = (appdata_t*)data;
204    
205     /* redraw the entire map by destroying all map items and redrawing them */
206     track_save(appdata->project, appdata->track.track);
207     diff_save(appdata->project, appdata->osm);
208     map_clear(appdata, MAP_LAYER_ALL);
209     osm_free(&appdata->icon, appdata->osm);
210    
211     appdata->osm = osm_parse(appdata->project->osm);
212     diff_restore(appdata, appdata->project, appdata->osm);
213     map_paint(appdata);
214    
215     appdata->track.track = track_restore(appdata, appdata->project);
216     if(appdata->track.track)
217     map_track_draw(appdata->map, appdata->track.track);
218    
219     wms_load(appdata);
220     }
221     #endif
222    
223     static void
224 harbaum 14 cb_menu_style(GtkWidget *widget, gpointer data) {
225 harbaum 1 appdata_t *appdata = (appdata_t*)data;
226    
227     style_select(GTK_WIDGET(appdata->window), appdata);
228     }
229    
230     static void
231 harbaum 14 cb_menu_map_no_icons(GtkWidget *widget, gpointer data) {
232 harbaum 1 appdata_t *appdata = (appdata_t*)data;
233    
234 harbaum 14 map_clear(appdata, MAP_LAYER_OBJECTS_ONLY);
235     appdata->settings->no_icons =
236     gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
237     map_paint(appdata);
238     }
239    
240     static void
241 harbaum 24 cb_menu_map_no_antialias(GtkWidget *widget, gpointer data) {
242     appdata_t *appdata = (appdata_t*)data;
243    
244     map_clear(appdata, MAP_LAYER_OBJECTS_ONLY);
245     appdata->settings->no_antialias =
246     gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
247     map_paint(appdata);
248     }
249    
250     static void
251 harbaum 14 cb_menu_save_changes(GtkWidget *widget, gpointer data) {
252     appdata_t *appdata = (appdata_t*)data;
253    
254 harbaum 1 diff_save(appdata->project, appdata->osm);
255 harbaum 14 statusbar_set(appdata, _("Saved all changes made "
256     "to this project so far"), FALSE);
257 harbaum 1 }
258    
259 harbaum 15 static void
260     cb_menu_undo_changes(GtkWidget *widget, gpointer data) {
261     appdata_t *appdata = (appdata_t*)data;
262 harbaum 1
263 harbaum 15 if(!yes_no_f(GTK_WIDGET(appdata->window), NULL, 0, 0,
264     _("Undo all changes?"),
265     _("Do you really want to undo all your changes "
266     "not uploaded so far? This cannot be undone!")))
267     return;
268    
269     map_clear(appdata, MAP_LAYER_OBJECTS_ONLY);
270     osm_free(&appdata->icon, appdata->osm);
271     diff_remove(appdata->project);
272     appdata->osm = osm_parse(appdata->project->osm);
273     map_paint(appdata);
274    
275     statusbar_set(appdata, _("All changes made "
276     "so far have been reset"), FALSE);
277     }
278    
279 harbaum 1 static void
280     cb_menu_fullscreen(GtkWidget *widget, gpointer data) {
281     appdata_t *appdata = (appdata_t *)data;
282    
283     if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)))
284     gtk_window_fullscreen(GTK_WINDOW(appdata->window));
285     else
286     gtk_window_unfullscreen(GTK_WINDOW(appdata->window));
287     }
288    
289     static void
290     cb_menu_zoomin(GtkWidget *widget, appdata_t *appdata) {
291     if(!appdata || !appdata->map) return;
292    
293     map_set_zoom(appdata->map, appdata->map->state->zoom*ZOOM_FACTOR_MENU, TRUE);
294     printf("zoom is now %f\n", appdata->map->state->zoom);
295     }
296    
297     static void
298     cb_menu_zoomout(GtkWidget *widget, appdata_t *appdata) {
299     if(!appdata || !appdata->map) return;
300    
301     map_set_zoom(appdata->map, appdata->map->state->zoom/ZOOM_FACTOR_MENU, TRUE);
302     printf("zoom is now %f\n", appdata->map->state->zoom);
303     }
304    
305     static void
306     cb_menu_track_import(GtkWidget *window, appdata_t *appdata) {
307    
308     /* open a file selector */
309     GtkWidget *dialog;
310    
311     #ifdef USE_HILDON
312     dialog = hildon_file_chooser_dialog_new(GTK_WINDOW(appdata->window),
313     GTK_FILE_CHOOSER_ACTION_OPEN);
314     #else
315     dialog = gtk_file_chooser_dialog_new (_("Import track file"),
316     GTK_WINDOW(appdata->window),
317     GTK_FILE_CHOOSER_ACTION_OPEN,
318     GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
319     GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
320     NULL);
321     #endif
322    
323     /* use path if one is present */
324     if(appdata->track.import_path)
325     gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),
326     appdata->track.import_path);
327    
328     gtk_widget_show_all (GTK_WIDGET(dialog));
329     if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_FM_OK) {
330     char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
331    
332     /* load a track */
333     track_do(appdata, TRACK_IMPORT, filename);
334     if(appdata->track.track) {
335    
336     /* save path if gpx was successfully loaded */
337     char *r = strrchr(filename, '/');
338    
339     /* there is a delimiter, use everything left of it as path */
340     if(r) {
341     *r = 0;
342     if(appdata->track.import_path) g_free(appdata->track.import_path);
343     appdata->track.import_path = g_strdup(filename);
344     /* restore path ... just in case ... */
345     *r = '/';
346     }
347     }
348     g_free (filename);
349     }
350    
351     gtk_widget_destroy (dialog);
352     }
353    
354     static void
355     cb_menu_track_gps(GtkWidget *window, gpointer data) {
356     appdata_t *appdata = (appdata_t*)data;
357    
358     if(gtk_check_menu_item_get_active(
359     GTK_CHECK_MENU_ITEM(appdata->track.menu_item_gps))) {
360     track_do(appdata, TRACK_GPS, NULL);
361     } else {
362     track_do(appdata, TRACK_NONE, NULL);
363     }
364     }
365    
366     static void
367     cb_menu_track_export(GtkWidget *window, gpointer data) {
368     appdata_t *appdata = (appdata_t*)data;
369     messagef(GTK_WIDGET(appdata->window), _("NIY"),
370     _("Track export is not yet supported."));
371     }
372    
373     static void
374     cb_menu_track_clear(GtkWidget *window, gpointer data) {
375     appdata_t *appdata = (appdata_t*)data;
376     track_do(appdata, TRACK_NONE, NULL);
377     }
378    
379     void menu_create(appdata_t *appdata) {
380     GtkWidget *menu, *item, *submenu;
381     menu = gtk_menu_new();
382    
383    
384     /* -------------------- Project submenu -------------------- */
385    
386     item = gtk_menu_item_new_with_label( _("Project") );
387     gtk_menu_append(GTK_MENU_SHELL(menu), item);
388     submenu = gtk_menu_new();
389     gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
390    
391     item = gtk_menu_item_new_with_label( _("Open...") );
392     gtk_menu_append(GTK_MENU_SHELL(submenu), item);
393     g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_project_open),
394     appdata);
395    
396     appdata->menu_item_project_close = item =
397     gtk_menu_item_new_with_label( _("Close") );
398     gtk_menu_append(GTK_MENU_SHELL(submenu), item);
399     g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_project_close),
400     appdata);
401    
402     /* --------------- view menu ------------------- */
403    
404     gtk_menu_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());
405    
406     appdata->menu_view = item =
407     gtk_menu_item_new_with_label( _("View") );
408     gtk_menu_append(GTK_MENU_SHELL(menu), item);
409     submenu = gtk_menu_new();
410     gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
411    
412 harbaum 22 appdata->menu_item_view_fullscreen =
413 harbaum 1 item = gtk_check_menu_item_new_with_label( _("Fullscreen") );
414     gtk_menu_append(GTK_MENU_SHELL(submenu), item);
415     g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_fullscreen),
416     appdata);
417    
418     item = gtk_menu_item_new_with_label( _("Zoom +" ));
419     gtk_menu_append(GTK_MENU_SHELL(submenu), item);
420     g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_zoomin), appdata);
421    
422     item = gtk_menu_item_new_with_label( _("Zoom -") );
423     gtk_menu_append(GTK_MENU_SHELL(submenu), item);
424 harbaum 4 g_signal_connect(item, "activate",
425     GTK_SIGNAL_FUNC(cb_menu_zoomout), appdata);
426 harbaum 1
427     /* -------------------- OSM submenu -------------------- */
428    
429     appdata->menu_osm = item = gtk_menu_item_new_with_label( _("OSM") );
430     gtk_menu_append(GTK_MENU_SHELL(menu), item);
431     submenu = gtk_menu_new();
432     gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
433    
434 harbaum 4 appdata->menu_item_osm_upload = item =
435     gtk_menu_item_new_with_label( _("Upload...") );
436 harbaum 1 gtk_menu_append(GTK_MENU_SHELL(submenu), item);
437     g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_upload), appdata);
438    
439     item = gtk_menu_item_new_with_label( _("Download...") );
440     gtk_menu_append(GTK_MENU_SHELL(submenu), item);
441 harbaum 4 g_signal_connect(item, "activate",
442     GTK_SIGNAL_FUNC(cb_menu_download), appdata);
443 harbaum 1
444     gtk_menu_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new());
445    
446 harbaum 4 appdata->menu_item_osm_diff = item =
447     gtk_menu_item_new_with_label( _("Save diff file") );
448 harbaum 1 gtk_menu_append(GTK_MENU_SHELL(submenu), item);
449     g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_save_changes),
450     appdata);
451    
452 harbaum 15 appdata->menu_item_osm_undo_changes = item =
453     gtk_menu_item_new_with_label( _("Undo all changes...") );
454     gtk_menu_append(GTK_MENU_SHELL(submenu), item);
455     g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_undo_changes),
456     appdata);
457    
458 harbaum 1 /* -------------------- wms submenu -------------------- */
459    
460     appdata->menu_wms = item = gtk_menu_item_new_with_label( _("WMS") );
461     gtk_menu_append(GTK_MENU_SHELL(menu), item);
462     submenu = gtk_menu_new();
463     gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
464    
465     item = gtk_menu_item_new_with_label( _("Import...") );
466     gtk_menu_append(GTK_MENU_SHELL(submenu), item);
467     g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_wms_import),
468     appdata);
469    
470     appdata->menu_item_wms_clear = item =
471     gtk_menu_item_new_with_label( _("Clear") );
472     gtk_menu_append(GTK_MENU_SHELL(submenu), item);
473     gtk_widget_set_sensitive(item, FALSE);
474     g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_wms_clear),
475     appdata);
476    
477     appdata->menu_item_wms_adjust = item =
478     gtk_menu_item_new_with_label( _("Adjust") );
479     gtk_menu_append(GTK_MENU_SHELL(submenu), item);
480     gtk_widget_set_sensitive(item, FALSE);
481     g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_wms_adjust),
482     appdata);
483    
484     /* -------------------- map submenu -------------------- */
485    
486     appdata->menu_map = item = gtk_menu_item_new_with_label( _("Map") );
487     gtk_menu_append(GTK_MENU_SHELL(menu), item);
488     submenu = gtk_menu_new();
489     gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
490    
491     appdata->menu_item_map_hide_sel = item =
492     gtk_menu_item_new_with_label( _("Hide selected") );
493     gtk_menu_append(GTK_MENU_SHELL(submenu), item);
494     gtk_widget_set_sensitive(item, FALSE);
495     g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_map_hide_sel),
496     appdata);
497    
498     appdata->menu_item_map_show_all = item =
499     gtk_menu_item_new_with_label( _("Show all") );
500     gtk_menu_append(GTK_MENU_SHELL(submenu), item);
501     gtk_widget_set_sensitive(item, FALSE);
502     g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_map_show_all),
503     appdata);
504    
505     gtk_menu_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new());
506    
507 harbaum 24 item = gtk_menu_item_new_with_label( _("Style...") );
508 harbaum 1 gtk_menu_append(GTK_MENU_SHELL(submenu), item);
509 harbaum 24 g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_style), appdata);
510 harbaum 1
511     gtk_menu_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new());
512    
513 harbaum 24 /* switches mainly intended for testing/debugging */
514     item = gtk_menu_item_new_with_label( _("Redraw") );
515 harbaum 1 gtk_menu_append(GTK_MENU_SHELL(submenu), item);
516 harbaum 24 g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_redraw), appdata);
517 harbaum 1
518 harbaum 14 appdata->menu_item_map_no_icons =
519     item = gtk_check_menu_item_new_with_label( _("No Icons") );
520     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item),
521     appdata->settings->no_icons);
522     gtk_menu_append(GTK_MENU_SHELL(submenu), item);
523     g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_map_no_icons),
524     appdata);
525    
526 harbaum 24 appdata->menu_item_map_no_antialias =
527     item = gtk_check_menu_item_new_with_label( _("No Antialias") );
528     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item),
529     appdata->settings->no_antialias);
530     gtk_menu_append(GTK_MENU_SHELL(submenu), item);
531     g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_map_no_antialias),
532     appdata);
533    
534 harbaum 1 /* -------------------- track submenu -------------------- */
535    
536     appdata->track.menu_track = item = gtk_menu_item_new_with_label(_("Track"));
537     gtk_menu_append(GTK_MENU_SHELL(menu), item);
538     submenu = gtk_menu_new();
539     gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
540    
541     appdata->track.menu_item_import =
542     item = gtk_menu_item_new_with_label( _("Import...") );
543     gtk_menu_append(GTK_MENU_SHELL(submenu), item);
544     g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_track_import),
545     appdata);
546    
547     appdata->track.menu_item_export =
548     item = gtk_menu_item_new_with_label( _("Export...") );
549     gtk_menu_append(GTK_MENU_SHELL(submenu), item);
550     g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_track_export),
551     appdata);
552    
553     appdata->track.menu_item_clear =
554     item = gtk_menu_item_new_with_label( _("Clear") );
555     gtk_menu_append(GTK_MENU_SHELL(submenu), item);
556     g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_track_clear),
557     appdata);
558    
559     appdata->track.menu_item_gps =
560     item = gtk_check_menu_item_new_with_label( _("GPS") );
561     gtk_menu_append(GTK_MENU_SHELL(submenu), item);
562     g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_track_gps),
563     appdata);
564    
565     /* ------------------------------------------------------- */
566    
567     gtk_menu_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());
568    
569    
570     item = gtk_menu_item_new_with_label( _("About...") );
571     gtk_menu_append(GTK_MENU_SHELL(menu), item);
572     g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_about), appdata);
573    
574    
575     item = gtk_menu_item_new_with_label( _("Quit") );
576     gtk_menu_append(GTK_MENU_SHELL(menu), item);
577     g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_quit), appdata);
578    
579     #ifdef USE_HILDON
580     hildon_window_set_menu(appdata->window, GTK_MENU(menu));
581     #else
582     /* attach ordinary gtk menu */
583     GtkWidget *menu_bar = gtk_menu_bar_new();
584    
585     GtkWidget *root_menu = gtk_menu_item_new_with_label (_("Menu"));
586     gtk_widget_show(root_menu);
587    
588     gtk_menu_bar_append(menu_bar, root_menu);
589     gtk_menu_item_set_submenu(GTK_MENU_ITEM (root_menu), menu);
590    
591     gtk_widget_show(menu_bar);
592     gtk_box_pack_start(GTK_BOX(appdata->vbox), menu_bar, 0, 0, 0);
593     #endif
594     }
595    
596     /********************* end of menu **********************/
597    
598    
599     void cleanup(appdata_t *appdata) {
600     settings_save(appdata->settings);
601    
602     #ifdef USE_HILDON
603     if(appdata->osso_context)
604     osso_deinitialize(appdata->osso_context);
605    
606     appdata->program = NULL;
607     #endif
608    
609     printf("waiting for gtk to shut down ");
610    
611     /* let gtk clean up first */
612     while(gtk_events_pending()) {
613     putchar('.');
614     gtk_main_iteration();
615     }
616    
617     printf(" ok\n");
618    
619     /* save project file */
620     if(appdata->project)
621     project_save(GTK_WIDGET(appdata->window), appdata->project);
622    
623     map_remove_bg_image(appdata->map);
624    
625     osm_free(&appdata->icon, appdata->osm);
626    
627     curl_global_cleanup();
628    
629     josm_presets_free(appdata->presets);
630    
631     icon_free_all(&appdata->icon);
632    
633     gps_release(appdata);
634    
635     settings_free(appdata->settings);
636    
637     statusbar_free(appdata->statusbar);
638    
639     iconbar_free(appdata->iconbar);
640    
641     project_free(appdata->project);
642    
643     puts("everything is gone");
644     }
645    
646     void on_window_destroy (GtkWidget *widget, gpointer data) {
647     appdata_t *appdata = (appdata_t*)data;
648    
649     gtk_main_quit();
650     appdata->window = NULL;
651     }
652    
653     gboolean on_window_key_press(GtkWidget *widget,
654     GdkEventKey *event, gpointer data) {
655     appdata_t *appdata = (appdata_t*)data;
656     int handled = FALSE;
657    
658     // the map handles some keys on its own ...
659     switch(event->keyval) {
660    
661 harbaum 22 #ifdef USE_HILDON
662     /* this is in fact a mapping to GDK_F6 */
663 harbaum 1 case HILDON_HARDKEY_FULLSCREEN:
664 harbaum 22 #else
665     case GDK_F11:
666     #endif
667     if(!gtk_check_menu_item_get_active(
668     GTK_CHECK_MENU_ITEM(appdata->menu_item_view_fullscreen))) {
669     gtk_window_fullscreen(GTK_WINDOW(appdata->window));
670 harbaum 1 gtk_check_menu_item_set_active(
671 harbaum 22 GTK_CHECK_MENU_ITEM(appdata->menu_item_view_fullscreen), TRUE);
672     } else {
673 harbaum 1 gtk_window_unfullscreen(GTK_WINDOW(appdata->window));
674 harbaum 22 gtk_check_menu_item_set_active(
675     GTK_CHECK_MENU_ITEM(appdata->menu_item_view_fullscreen), FALSE);
676     }
677    
678     handled = TRUE;
679 harbaum 1 break;
680     }
681    
682     /* forward unprocessed key presses to map */
683     if(!handled && appdata->project && appdata->osm)
684     handled = map_key_press_event(appdata, event);
685    
686     return handled;
687     }
688    
689     int main(int argc, char *argv[]) {
690     appdata_t appdata;
691    
692     /* init appdata */
693     memset(&appdata, 0, sizeof(appdata));
694    
695     printf("Using locale for %s in %s\n", PACKAGE, LOCALEDIR);
696    
697     setlocale(LC_ALL, "");
698     bindtextdomain(PACKAGE, LOCALEDIR);
699     bind_textdomain_codeset(PACKAGE, "UTF-8");
700     textdomain(PACKAGE);
701    
702     /* Must initialize libcurl before any threads are started */
703     curl_global_init(CURL_GLOBAL_ALL);
704    
705     g_thread_init(NULL);
706    
707     gps_init(&appdata);
708    
709     gtk_init (&argc, &argv);
710    
711     #ifdef USE_HILDON
712     printf("Installing osso context for \"org.harbaum." PACKAGE "\"\n");
713     appdata.osso_context = osso_initialize("org.harbaum."PACKAGE,
714     VERSION, TRUE, NULL);
715     if(appdata.osso_context == NULL)
716     fprintf(stderr, "error initiating osso context\n");
717    
718     dbus_register(&appdata);
719     #endif
720    
721     #ifdef USE_HILDON
722     /* Create the hildon program and setup the title */
723     appdata.program = HILDON_PROGRAM(hildon_program_get_instance());
724     g_set_application_name("OSM2Go");
725    
726     /* Create HildonWindow and set it to HildonProgram */
727     appdata.window = HILDON_WINDOW(hildon_window_new());
728     hildon_program_add_window(appdata.program, appdata.window);
729     #else
730     /* Create a Window. */
731     appdata.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
732     gtk_window_set_title(GTK_WINDOW(appdata.window), "OSM2Go");
733     /* Set a decent default size for the window. */
734     gtk_window_set_default_size(GTK_WINDOW(appdata.window),
735     DEFAULT_WIDTH, DEFAULT_HEIGHT);
736     gtk_window_set_icon(GTK_WINDOW(appdata.window),
737     icon_load(&appdata.icon, PACKAGE));
738     #endif
739    
740     g_signal_connect(G_OBJECT(appdata.window), "destroy",
741     G_CALLBACK(on_window_destroy), &appdata);
742    
743     g_signal_connect(G_OBJECT(appdata.window), "key_press_event",
744     G_CALLBACK(on_window_key_press), &appdata);
745    
746 harbaum 14 /* user specific init */
747     appdata.settings = settings_load();
748    
749 harbaum 1 appdata.vbox = gtk_vbox_new(FALSE,0);
750     menu_create(&appdata);
751    
752     /* ----------------------- setup main window ---------------- */
753    
754     GtkWidget *hbox = gtk_hbox_new(FALSE,0);
755     GtkWidget *vbox = gtk_vbox_new(FALSE,0);
756    
757     #ifdef PORTRAIT
758     gtk_box_pack_start(GTK_BOX(vbox), iconbar_new(&appdata), FALSE, FALSE, 0);
759     #endif
760 harbaum 22
761     /* generate main map view */
762     GtkWidget *map = map_new(&appdata);
763     if(!map) {
764     cleanup(&appdata);
765     return -1;
766     }
767    
768     gtk_box_pack_start(GTK_BOX(vbox), map, TRUE, TRUE, 0);
769 harbaum 1 gtk_box_pack_start(GTK_BOX(vbox), statusbar_new(&appdata), FALSE, FALSE, 0);
770    
771     #ifndef PORTRAIT
772     gtk_box_pack_start(GTK_BOX(hbox), iconbar_new(&appdata), FALSE, FALSE, 0);
773     #endif
774     gtk_box_pack_start(GTK_BOX(hbox), gtk_vseparator_new(), FALSE, FALSE, 0);
775     gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
776    
777     gtk_box_pack_start(GTK_BOX(appdata.vbox), hbox, TRUE, TRUE, 0);
778    
779     gtk_container_add(GTK_CONTAINER(appdata.window), appdata.vbox);
780    
781     gtk_widget_show_all(GTK_WIDGET(appdata.window));
782    
783     appdata.presets = josm_presets_load();
784    
785     /* let gtk do its thing before loading the data, */
786     /* so the user sees something */
787     while(gtk_events_pending()) {
788     putchar('.');
789     gtk_main_iteration();
790     }
791    
792     /* load project if one is specified in the settings */
793     if(appdata.settings->project)
794     project_load(&appdata, appdata.settings->project);
795    
796 harbaum 4 main_ui_enable(&appdata);
797 harbaum 1
798     /* ------------ jump into main loop ---------------- */
799    
800     gtk_main();
801    
802 harbaum 4 puts("gtk_main() left");
803    
804 harbaum 1 track_save(appdata.project, appdata.track.track);
805    
806     /* save a diff if there are dirty entries */
807     diff_save(appdata.project, appdata.osm);
808    
809     cleanup(&appdata);
810    
811     return 0;
812     }