Contents of /trunk/src/main.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 22 - (show annotations)
Wed Dec 17 16:43:46 2008 UTC (15 years, 4 months ago) by harbaum
File MIME type: text/plain
File size: 24281 byte(s)
Color system cleaned up, desktop fullscreen
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 #include <gdk/gdkkeysyms.h>
23
24 #include "appdata.h"
25
26 /* disable/enable main screen control dependant on presence of open project */
27 static void main_ui_enable(appdata_t *appdata) {
28 gboolean project_valid = (appdata->project != NULL);
29 gboolean osm_valid = (appdata->osm != NULL);
30
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 if(project_valid)
39 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 if(project_valid)
47 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 gtk_widget_set_sensitive(appdata->iconbar->toolbar, osm_valid);
54
55 /* disable all menu entries related to map */
56 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 gtk_widget_set_sensitive(appdata->menu_item_osm_undo_changes, osm_valid);
60 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
66 if(!project_valid)
67 statusbar_set(appdata, _("Please load or create a project"), FALSE);
68 }
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 { MENU_SUB, "_OSM", NULL },
80
81 { 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 main_ui_enable(appdata);
90 }
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 main_ui_enable(appdata);
97 }
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 if(!appdata->project) return;
145
146 /* 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
153 appdata->osm = NULL;
154 }
155
156 // download
157 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
163 main_ui_enable(appdata);
164 }
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 /* ---------------------------------------------------------- */
199
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 cb_menu_style(GtkWidget *widget, gpointer data) {
225 appdata_t *appdata = (appdata_t*)data;
226
227 style_select(GTK_WIDGET(appdata->window), appdata);
228 }
229
230 static void
231 cb_menu_map_no_icons(GtkWidget *widget, gpointer data) {
232 appdata_t *appdata = (appdata_t*)data;
233
234 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 cb_menu_save_changes(GtkWidget *widget, gpointer data) {
242 appdata_t *appdata = (appdata_t*)data;
243
244 diff_save(appdata->project, appdata->osm);
245 statusbar_set(appdata, _("Saved all changes made "
246 "to this project so far"), FALSE);
247 }
248
249 static void
250 cb_menu_undo_changes(GtkWidget *widget, gpointer data) {
251 appdata_t *appdata = (appdata_t*)data;
252
253 if(!yes_no_f(GTK_WIDGET(appdata->window), NULL, 0, 0,
254 _("Undo all changes?"),
255 _("Do you really want to undo all your changes "
256 "not uploaded so far? This cannot be undone!")))
257 return;
258
259 map_clear(appdata, MAP_LAYER_OBJECTS_ONLY);
260 osm_free(&appdata->icon, appdata->osm);
261 diff_remove(appdata->project);
262 appdata->osm = osm_parse(appdata->project->osm);
263 map_paint(appdata);
264
265 statusbar_set(appdata, _("All changes made "
266 "so far have been reset"), FALSE);
267 }
268
269 static void
270 cb_menu_fullscreen(GtkWidget *widget, gpointer data) {
271 appdata_t *appdata = (appdata_t *)data;
272
273 if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)))
274 gtk_window_fullscreen(GTK_WINDOW(appdata->window));
275 else
276 gtk_window_unfullscreen(GTK_WINDOW(appdata->window));
277 }
278
279 static void
280 cb_menu_zoomin(GtkWidget *widget, appdata_t *appdata) {
281 if(!appdata || !appdata->map) return;
282
283 map_set_zoom(appdata->map, appdata->map->state->zoom*ZOOM_FACTOR_MENU, TRUE);
284 printf("zoom is now %f\n", appdata->map->state->zoom);
285 }
286
287 static void
288 cb_menu_zoomout(GtkWidget *widget, appdata_t *appdata) {
289 if(!appdata || !appdata->map) return;
290
291 map_set_zoom(appdata->map, appdata->map->state->zoom/ZOOM_FACTOR_MENU, TRUE);
292 printf("zoom is now %f\n", appdata->map->state->zoom);
293 }
294
295 static void
296 cb_menu_track_import(GtkWidget *window, appdata_t *appdata) {
297
298 /* open a file selector */
299 GtkWidget *dialog;
300
301 #ifdef USE_HILDON
302 dialog = hildon_file_chooser_dialog_new(GTK_WINDOW(appdata->window),
303 GTK_FILE_CHOOSER_ACTION_OPEN);
304 #else
305 dialog = gtk_file_chooser_dialog_new (_("Import track file"),
306 GTK_WINDOW(appdata->window),
307 GTK_FILE_CHOOSER_ACTION_OPEN,
308 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
309 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
310 NULL);
311 #endif
312
313 /* use path if one is present */
314 if(appdata->track.import_path)
315 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),
316 appdata->track.import_path);
317
318 gtk_widget_show_all (GTK_WIDGET(dialog));
319 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_FM_OK) {
320 char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
321
322 /* load a track */
323 track_do(appdata, TRACK_IMPORT, filename);
324 if(appdata->track.track) {
325
326 /* save path if gpx was successfully loaded */
327 char *r = strrchr(filename, '/');
328
329 /* there is a delimiter, use everything left of it as path */
330 if(r) {
331 *r = 0;
332 if(appdata->track.import_path) g_free(appdata->track.import_path);
333 appdata->track.import_path = g_strdup(filename);
334 /* restore path ... just in case ... */
335 *r = '/';
336 }
337 }
338 g_free (filename);
339 }
340
341 gtk_widget_destroy (dialog);
342 }
343
344 static void
345 cb_menu_track_gps(GtkWidget *window, gpointer data) {
346 appdata_t *appdata = (appdata_t*)data;
347
348 if(gtk_check_menu_item_get_active(
349 GTK_CHECK_MENU_ITEM(appdata->track.menu_item_gps))) {
350 track_do(appdata, TRACK_GPS, NULL);
351 } else {
352 track_do(appdata, TRACK_NONE, NULL);
353 }
354 }
355
356 static void
357 cb_menu_track_export(GtkWidget *window, gpointer data) {
358 appdata_t *appdata = (appdata_t*)data;
359 messagef(GTK_WIDGET(appdata->window), _("NIY"),
360 _("Track export is not yet supported."));
361 }
362
363 static void
364 cb_menu_track_clear(GtkWidget *window, gpointer data) {
365 appdata_t *appdata = (appdata_t*)data;
366 track_do(appdata, TRACK_NONE, NULL);
367 }
368
369 void menu_create(appdata_t *appdata) {
370 GtkWidget *menu, *item, *submenu;
371 menu = gtk_menu_new();
372
373
374 /* -------------------- Project submenu -------------------- */
375
376 item = gtk_menu_item_new_with_label( _("Project") );
377 gtk_menu_append(GTK_MENU_SHELL(menu), item);
378 submenu = gtk_menu_new();
379 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
380
381 item = gtk_menu_item_new_with_label( _("Open...") );
382 gtk_menu_append(GTK_MENU_SHELL(submenu), item);
383 g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_project_open),
384 appdata);
385
386 appdata->menu_item_project_close = item =
387 gtk_menu_item_new_with_label( _("Close") );
388 gtk_menu_append(GTK_MENU_SHELL(submenu), item);
389 g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_project_close),
390 appdata);
391
392 /* --------------- view menu ------------------- */
393
394 gtk_menu_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());
395
396 appdata->menu_view = item =
397 gtk_menu_item_new_with_label( _("View") );
398 gtk_menu_append(GTK_MENU_SHELL(menu), item);
399 submenu = gtk_menu_new();
400 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
401
402 appdata->menu_item_view_fullscreen =
403 item = gtk_check_menu_item_new_with_label( _("Fullscreen") );
404 gtk_menu_append(GTK_MENU_SHELL(submenu), item);
405 g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_fullscreen),
406 appdata);
407
408 item = gtk_menu_item_new_with_label( _("Zoom +" ));
409 gtk_menu_append(GTK_MENU_SHELL(submenu), item);
410 g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_zoomin), appdata);
411
412 item = gtk_menu_item_new_with_label( _("Zoom -") );
413 gtk_menu_append(GTK_MENU_SHELL(submenu), item);
414 g_signal_connect(item, "activate",
415 GTK_SIGNAL_FUNC(cb_menu_zoomout), appdata);
416
417 /* -------------------- OSM submenu -------------------- */
418
419 appdata->menu_osm = item = gtk_menu_item_new_with_label( _("OSM") );
420 gtk_menu_append(GTK_MENU_SHELL(menu), item);
421 submenu = gtk_menu_new();
422 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
423
424 appdata->menu_item_osm_upload = item =
425 gtk_menu_item_new_with_label( _("Upload...") );
426 gtk_menu_append(GTK_MENU_SHELL(submenu), item);
427 g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_upload), appdata);
428
429 item = gtk_menu_item_new_with_label( _("Download...") );
430 gtk_menu_append(GTK_MENU_SHELL(submenu), item);
431 g_signal_connect(item, "activate",
432 GTK_SIGNAL_FUNC(cb_menu_download), appdata);
433
434 gtk_menu_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new());
435
436 appdata->menu_item_osm_diff = item =
437 gtk_menu_item_new_with_label( _("Save diff file") );
438 gtk_menu_append(GTK_MENU_SHELL(submenu), item);
439 g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_save_changes),
440 appdata);
441
442 appdata->menu_item_osm_undo_changes = item =
443 gtk_menu_item_new_with_label( _("Undo all changes...") );
444 gtk_menu_append(GTK_MENU_SHELL(submenu), item);
445 g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_undo_changes),
446 appdata);
447
448 /* -------------------- wms submenu -------------------- */
449
450 appdata->menu_wms = item = gtk_menu_item_new_with_label( _("WMS") );
451 gtk_menu_append(GTK_MENU_SHELL(menu), item);
452 submenu = gtk_menu_new();
453 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
454
455 item = gtk_menu_item_new_with_label( _("Import...") );
456 gtk_menu_append(GTK_MENU_SHELL(submenu), item);
457 g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_wms_import),
458 appdata);
459
460 appdata->menu_item_wms_clear = item =
461 gtk_menu_item_new_with_label( _("Clear") );
462 gtk_menu_append(GTK_MENU_SHELL(submenu), item);
463 gtk_widget_set_sensitive(item, FALSE);
464 g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_wms_clear),
465 appdata);
466
467 appdata->menu_item_wms_adjust = item =
468 gtk_menu_item_new_with_label( _("Adjust") );
469 gtk_menu_append(GTK_MENU_SHELL(submenu), item);
470 gtk_widget_set_sensitive(item, FALSE);
471 g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_wms_adjust),
472 appdata);
473
474 /* -------------------- map submenu -------------------- */
475
476 appdata->menu_map = item = gtk_menu_item_new_with_label( _("Map") );
477 gtk_menu_append(GTK_MENU_SHELL(menu), item);
478 submenu = gtk_menu_new();
479 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
480
481 appdata->menu_item_map_hide_sel = item =
482 gtk_menu_item_new_with_label( _("Hide selected") );
483 gtk_menu_append(GTK_MENU_SHELL(submenu), item);
484 gtk_widget_set_sensitive(item, FALSE);
485 g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_map_hide_sel),
486 appdata);
487
488 appdata->menu_item_map_show_all = item =
489 gtk_menu_item_new_with_label( _("Show all") );
490 gtk_menu_append(GTK_MENU_SHELL(submenu), item);
491 gtk_widget_set_sensitive(item, FALSE);
492 g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_map_show_all),
493 appdata);
494
495 gtk_menu_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new());
496
497 item = gtk_menu_item_new_with_label( _("Redraw") );
498 gtk_menu_append(GTK_MENU_SHELL(submenu), item);
499 g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_redraw), appdata);
500
501 gtk_menu_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new());
502
503 item = gtk_menu_item_new_with_label( _("Style...") );
504 gtk_menu_append(GTK_MENU_SHELL(submenu), item);
505 g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_style), appdata);
506
507 appdata->menu_item_map_no_icons =
508 item = gtk_check_menu_item_new_with_label( _("No Icons") );
509 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item),
510 appdata->settings->no_icons);
511 gtk_menu_append(GTK_MENU_SHELL(submenu), item);
512 g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_map_no_icons),
513 appdata);
514
515 /* -------------------- track submenu -------------------- */
516
517 appdata->track.menu_track = item = gtk_menu_item_new_with_label(_("Track"));
518 gtk_menu_append(GTK_MENU_SHELL(menu), item);
519 submenu = gtk_menu_new();
520 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
521
522 appdata->track.menu_item_import =
523 item = gtk_menu_item_new_with_label( _("Import...") );
524 gtk_menu_append(GTK_MENU_SHELL(submenu), item);
525 g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_track_import),
526 appdata);
527
528 appdata->track.menu_item_export =
529 item = gtk_menu_item_new_with_label( _("Export...") );
530 gtk_menu_append(GTK_MENU_SHELL(submenu), item);
531 g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_track_export),
532 appdata);
533
534 appdata->track.menu_item_clear =
535 item = gtk_menu_item_new_with_label( _("Clear") );
536 gtk_menu_append(GTK_MENU_SHELL(submenu), item);
537 g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_track_clear),
538 appdata);
539
540 appdata->track.menu_item_gps =
541 item = gtk_check_menu_item_new_with_label( _("GPS") );
542 gtk_menu_append(GTK_MENU_SHELL(submenu), item);
543 g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_track_gps),
544 appdata);
545
546 /* ------------------------------------------------------- */
547
548 gtk_menu_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());
549
550
551 item = gtk_menu_item_new_with_label( _("About...") );
552 gtk_menu_append(GTK_MENU_SHELL(menu), item);
553 g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_about), appdata);
554
555
556 item = gtk_menu_item_new_with_label( _("Quit") );
557 gtk_menu_append(GTK_MENU_SHELL(menu), item);
558 g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_quit), appdata);
559
560 #ifdef USE_HILDON
561 hildon_window_set_menu(appdata->window, GTK_MENU(menu));
562 #else
563 /* attach ordinary gtk menu */
564 GtkWidget *menu_bar = gtk_menu_bar_new();
565
566 GtkWidget *root_menu = gtk_menu_item_new_with_label (_("Menu"));
567 gtk_widget_show(root_menu);
568
569 gtk_menu_bar_append(menu_bar, root_menu);
570 gtk_menu_item_set_submenu(GTK_MENU_ITEM (root_menu), menu);
571
572 gtk_widget_show(menu_bar);
573 gtk_box_pack_start(GTK_BOX(appdata->vbox), menu_bar, 0, 0, 0);
574 #endif
575 }
576
577 /********************* end of menu **********************/
578
579
580 void cleanup(appdata_t *appdata) {
581 settings_save(appdata->settings);
582
583 #ifdef USE_HILDON
584 if(appdata->osso_context)
585 osso_deinitialize(appdata->osso_context);
586
587 appdata->program = NULL;
588 #endif
589
590 printf("waiting for gtk to shut down ");
591
592 /* let gtk clean up first */
593 while(gtk_events_pending()) {
594 putchar('.');
595 gtk_main_iteration();
596 }
597
598 printf(" ok\n");
599
600 /* save project file */
601 if(appdata->project)
602 project_save(GTK_WIDGET(appdata->window), appdata->project);
603
604 map_remove_bg_image(appdata->map);
605
606 osm_free(&appdata->icon, appdata->osm);
607
608 curl_global_cleanup();
609
610 josm_presets_free(appdata->presets);
611
612 icon_free_all(&appdata->icon);
613
614 gps_release(appdata);
615
616 settings_free(appdata->settings);
617
618 statusbar_free(appdata->statusbar);
619
620 iconbar_free(appdata->iconbar);
621
622 project_free(appdata->project);
623
624 puts("everything is gone");
625 }
626
627 void on_window_destroy (GtkWidget *widget, gpointer data) {
628 appdata_t *appdata = (appdata_t*)data;
629
630 gtk_main_quit();
631 appdata->window = NULL;
632 }
633
634 gboolean on_window_key_press(GtkWidget *widget,
635 GdkEventKey *event, gpointer data) {
636 appdata_t *appdata = (appdata_t*)data;
637 int handled = FALSE;
638
639 // the map handles some keys on its own ...
640 switch(event->keyval) {
641
642 #ifdef USE_HILDON
643 /* this is in fact a mapping to GDK_F6 */
644 case HILDON_HARDKEY_FULLSCREEN:
645 #else
646 case GDK_F11:
647 #endif
648 if(!gtk_check_menu_item_get_active(
649 GTK_CHECK_MENU_ITEM(appdata->menu_item_view_fullscreen))) {
650 gtk_window_fullscreen(GTK_WINDOW(appdata->window));
651 gtk_check_menu_item_set_active(
652 GTK_CHECK_MENU_ITEM(appdata->menu_item_view_fullscreen), TRUE);
653 } else {
654 gtk_window_unfullscreen(GTK_WINDOW(appdata->window));
655 gtk_check_menu_item_set_active(
656 GTK_CHECK_MENU_ITEM(appdata->menu_item_view_fullscreen), FALSE);
657 }
658
659 handled = TRUE;
660 break;
661 }
662
663 /* forward unprocessed key presses to map */
664 if(!handled && appdata->project && appdata->osm)
665 handled = map_key_press_event(appdata, event);
666
667 return handled;
668 }
669
670 int main(int argc, char *argv[]) {
671 appdata_t appdata;
672
673 /* init appdata */
674 memset(&appdata, 0, sizeof(appdata));
675
676 printf("Using locale for %s in %s\n", PACKAGE, LOCALEDIR);
677
678 setlocale(LC_ALL, "");
679 bindtextdomain(PACKAGE, LOCALEDIR);
680 bind_textdomain_codeset(PACKAGE, "UTF-8");
681 textdomain(PACKAGE);
682
683 /* Must initialize libcurl before any threads are started */
684 curl_global_init(CURL_GLOBAL_ALL);
685
686 g_thread_init(NULL);
687
688 gps_init(&appdata);
689
690 gtk_init (&argc, &argv);
691
692 #ifdef USE_HILDON
693 printf("Installing osso context for \"org.harbaum." PACKAGE "\"\n");
694 appdata.osso_context = osso_initialize("org.harbaum."PACKAGE,
695 VERSION, TRUE, NULL);
696 if(appdata.osso_context == NULL)
697 fprintf(stderr, "error initiating osso context\n");
698
699 dbus_register(&appdata);
700 #endif
701
702 #ifdef USE_HILDON
703 /* Create the hildon program and setup the title */
704 appdata.program = HILDON_PROGRAM(hildon_program_get_instance());
705 g_set_application_name("OSM2Go");
706
707 /* Create HildonWindow and set it to HildonProgram */
708 appdata.window = HILDON_WINDOW(hildon_window_new());
709 hildon_program_add_window(appdata.program, appdata.window);
710 #else
711 /* Create a Window. */
712 appdata.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
713 gtk_window_set_title(GTK_WINDOW(appdata.window), "OSM2Go");
714 /* Set a decent default size for the window. */
715 gtk_window_set_default_size(GTK_WINDOW(appdata.window),
716 DEFAULT_WIDTH, DEFAULT_HEIGHT);
717 gtk_window_set_icon(GTK_WINDOW(appdata.window),
718 icon_load(&appdata.icon, PACKAGE));
719 #endif
720
721 g_signal_connect(G_OBJECT(appdata.window), "destroy",
722 G_CALLBACK(on_window_destroy), &appdata);
723
724 g_signal_connect(G_OBJECT(appdata.window), "key_press_event",
725 G_CALLBACK(on_window_key_press), &appdata);
726
727 /* user specific init */
728 appdata.settings = settings_load();
729
730 appdata.vbox = gtk_vbox_new(FALSE,0);
731 menu_create(&appdata);
732
733 /* ----------------------- setup main window ---------------- */
734
735 GtkWidget *hbox = gtk_hbox_new(FALSE,0);
736 GtkWidget *vbox = gtk_vbox_new(FALSE,0);
737
738 #ifdef PORTRAIT
739 gtk_box_pack_start(GTK_BOX(vbox), iconbar_new(&appdata), FALSE, FALSE, 0);
740 #endif
741
742 /* generate main map view */
743 GtkWidget *map = map_new(&appdata);
744 if(!map) {
745 cleanup(&appdata);
746 return -1;
747 }
748
749 gtk_box_pack_start(GTK_BOX(vbox), map, TRUE, TRUE, 0);
750 gtk_box_pack_start(GTK_BOX(vbox), statusbar_new(&appdata), FALSE, FALSE, 0);
751
752 #ifndef PORTRAIT
753 gtk_box_pack_start(GTK_BOX(hbox), iconbar_new(&appdata), FALSE, FALSE, 0);
754 #endif
755 gtk_box_pack_start(GTK_BOX(hbox), gtk_vseparator_new(), FALSE, FALSE, 0);
756 gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
757
758 gtk_box_pack_start(GTK_BOX(appdata.vbox), hbox, TRUE, TRUE, 0);
759
760 gtk_container_add(GTK_CONTAINER(appdata.window), appdata.vbox);
761
762 gtk_widget_show_all(GTK_WIDGET(appdata.window));
763
764 appdata.presets = josm_presets_load();
765
766 /* let gtk do its thing before loading the data, */
767 /* so the user sees something */
768 while(gtk_events_pending()) {
769 putchar('.');
770 gtk_main_iteration();
771 }
772
773 /* load project if one is specified in the settings */
774 if(appdata.settings->project)
775 project_load(&appdata, appdata.settings->project);
776
777 main_ui_enable(&appdata);
778
779 /* ------------ jump into main loop ---------------- */
780
781 gtk_main();
782
783 puts("gtk_main() left");
784
785 track_save(appdata.project, appdata.track.track);
786
787 /* save a diff if there are dirty entries */
788 diff_save(appdata.project, appdata.osm);
789
790 cleanup(&appdata);
791
792 return 0;
793 }