Contents of /trunk/src/main.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 207 - (hide annotations)
Fri Jul 10 12:13:34 2009 UTC (14 years, 10 months ago) by harbaum
File MIME type: text/plain
File size: 44414 byte(s)
Project consistency fix
1 harbaum 1 /*
2 achadwick 101 * Copyright (C) 2008 Till Harbaum <till@harbaum.org>.
3     *
4 harbaum 1 * This file is part of OSM2Go.
5     *
6     * OSM2Go 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     * OSM2Go 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 OSM2Go. If not, see <http://www.gnu.org/licenses/>.
18     */
19    
20     #include <stdio.h>
21     #include <string.h>
22    
23     #include <curl/curl.h>
24 harbaum 22 #include <gdk/gdkkeysyms.h>
25 harbaum 1
26 harbaum 188 #if defined(USE_HILDON) && (MAEMO_VERSION_MAJOR == 5)
27     #include <hildon/hildon-button.h>
28     #include <hildon/hildon-check-button.h>
29     #include <hildon/hildon-window-stack.h>
30 harbaum 190 #include <gdk/gdkx.h>
31     #include <X11/Xatom.h>
32 harbaum 188 #endif
33    
34 harbaum 1 #include "appdata.h"
35 achadwick 28 #include "banner.h"
36 harbaum 1
37     /* disable/enable main screen control dependant on presence of open project */
38 harbaum 4 static void main_ui_enable(appdata_t *appdata) {
39     gboolean project_valid = (appdata->project != NULL);
40     gboolean osm_valid = (appdata->osm != NULL);
41 harbaum 1
42     /* cancel any action in progress */
43     if(GTK_WIDGET_FLAGS(appdata->iconbar->cancel) & GTK_SENSITIVE)
44     map_action_cancel(appdata);
45    
46     /* ---- set project name as window title ----- */
47 harbaum 176 #if defined(USE_HILDON) && MAEMO_VERSION_MAJOR < 5
48     if(project_valid)
49     gtk_window_set_title(GTK_WINDOW(appdata->window), appdata->project->name);
50     else
51     gtk_window_set_title(GTK_WINDOW(appdata->window), "");
52     #else
53 harbaum 1 char *str = NULL;
54 harbaum 4 if(project_valid)
55 harbaum 1 str = g_strdup_printf("OSM2Go - %s", appdata->project->name);
56     else
57     str = g_strdup_printf("OSM2Go");
58    
59     gtk_window_set_title(GTK_WINDOW(appdata->window), str);
60     g_free(str);
61     #endif
62    
63     if(appdata->iconbar && appdata->iconbar->toolbar)
64 harbaum 4 gtk_widget_set_sensitive(appdata->iconbar->toolbar, osm_valid);
65 harbaum 1 /* disable all menu entries related to map */
66 harbaum 188 gtk_widget_set_sensitive(appdata->submenu_map, project_valid);
67     gtk_widget_set_sensitive(appdata->menu_item_map_upload, osm_valid);
68     if(appdata->menu_item_map_undo)
69     gtk_widget_set_sensitive(appdata->menu_item_map_undo, osm_valid);
70     gtk_widget_set_sensitive(appdata->menu_item_map_save_changes, osm_valid);
71     gtk_widget_set_sensitive(appdata->menu_item_map_undo_changes, osm_valid);
72     gtk_widget_set_sensitive(appdata->menu_item_map_relations, osm_valid);
73     gtk_widget_set_sensitive(appdata->track.submenu_track, osm_valid);
74     gtk_widget_set_sensitive(appdata->submenu_view, osm_valid);
75     gtk_widget_set_sensitive(appdata->submenu_wms, osm_valid);
76 harbaum 1
77 harbaum 195 #ifdef ZOOM_BUTTONS
78     gtk_widget_set_sensitive(appdata->btn_zoom_in, osm_valid);
79     gtk_widget_set_sensitive(appdata->btn_zoom_out, osm_valid);
80     #endif
81    
82 harbaum 4 if(!project_valid)
83 achadwick 6 statusbar_set(appdata, _("Please load or create a project"), FALSE);
84 harbaum 1 }
85    
86     /******************** begin of menu *********************/
87    
88     static void
89 harbaum 139 cb_menu_project_open(GtkMenuItem *item, gpointer data) {
90 harbaum 1 appdata_t *appdata = (appdata_t*)data;
91     project_load(appdata, NULL);
92 harbaum 4 main_ui_enable(appdata);
93 harbaum 1 }
94    
95     static void
96 harbaum 185 cb_menu_project_wizard(GtkMenuItem *item, gpointer data) {
97 harbaum 1 appdata_t *appdata = (appdata_t*)data;
98 harbaum 185 project_wizard(appdata);
99 harbaum 1 }
100    
101     static void
102 harbaum 139 cb_menu_about(GtkMenuItem *item, gpointer data) {
103     appdata_t *appdata = (appdata_t*)data;
104 harbaum 1
105     const gchar *authors[] = {
106     "Till Harbaum <till@harbaum.org>",
107 achadwick 28 "Andrew Chadwick <andrewc-osm2go@piffle.org>",
108 harbaum 200 "Marcus Bauer <marcus.bauer@gmail.com>",
109     "John Stowers <john.stowers@gmail.com>",
110 harbaum 1 NULL };
111    
112 harbaum 139 const gchar *artists[] = {
113 harbaum 140 "Andrew Zhilin <drew.zhilin@gmail.com>",
114 harbaum 139 NULL };
115 harbaum 1
116 harbaum 139 gtk_show_about_dialog(GTK_WINDOW(appdata->window),
117 harbaum 140 "name", "OSM2Go",
118 harbaum 139 "version", VERSION,
119     "copyright", _("Copyright 2008-2009"),
120     "authors", authors,
121     "artists", artists,
122     "website", _("http://www.harbaum.org/till/maemo"),
123     "comments", _("Mobile OSM Editor"),
124     NULL);
125 harbaum 1 }
126    
127     void on_window_destroy (GtkWidget *widget, gpointer data);
128    
129 harbaum 188 #ifndef USE_HILDON
130 harbaum 1 static void
131 harbaum 139 cb_menu_quit(GtkMenuItem *item, gpointer data) {
132 harbaum 1 appdata_t *appdata = (appdata_t*)data;
133     gtk_widget_destroy(GTK_WIDGET(appdata->window));
134     }
135 harbaum 188 #endif
136 harbaum 1
137     static void
138 harbaum 139 cb_menu_upload(GtkMenuItem *item, gpointer data) {
139 harbaum 1 appdata_t *appdata = (appdata_t*)data;
140     if(!appdata->osm || !appdata->project) return;
141    
142 harbaum 179 if(project_check_demo(GTK_WIDGET(appdata->window), appdata->project))
143 harbaum 178 return;
144    
145 harbaum 1 osm_upload(appdata, appdata->osm, appdata->project);
146     }
147    
148     static void
149 harbaum 139 cb_menu_download(GtkMenuItem *item, gpointer data) {
150 harbaum 1 appdata_t *appdata = (appdata_t*)data;
151 harbaum 4 if(!appdata->project) return;
152 harbaum 1
153 harbaum 179 if(project_check_demo(GTK_WIDGET(appdata->window), appdata->project))
154 harbaum 178 return;
155    
156 harbaum 4 /* if we have valid osm data loaded: save state first */
157     if(appdata->osm) {
158     /* redraw the entire map by destroying all map items and redrawing them */
159     diff_save(appdata->project, appdata->osm);
160     map_clear(appdata, MAP_LAYER_OBJECTS_ONLY);
161     osm_free(&appdata->icon, appdata->osm);
162 harbaum 1
163 harbaum 4 appdata->osm = NULL;
164     }
165    
166 harbaum 1 // download
167 harbaum 169 if(osm_download(GTK_WIDGET(appdata->window), appdata->settings,
168     appdata->project)) {
169 harbaum 177 banner_busy_start(appdata, 1, "Redrawing");
170 harbaum 175 appdata->osm = osm_parse(appdata->project->path, appdata->project->osm);
171 harbaum 4 diff_restore(appdata, appdata->project, appdata->osm);
172     map_paint(appdata);
173 harbaum 177 banner_busy_stop(appdata); //"Redrawing"
174 harbaum 4 }
175 harbaum 1
176 harbaum 4 main_ui_enable(appdata);
177 harbaum 1 }
178    
179     static void
180 harbaum 139 cb_menu_wms_import(GtkMenuItem *item, gpointer data) {
181 harbaum 1 appdata_t *appdata = (appdata_t*)data;
182     wms_import(appdata);
183     }
184    
185     static void
186 harbaum 139 cb_menu_wms_clear(GtkMenuItem *item, gpointer data) {
187 harbaum 1 appdata_t *appdata = (appdata_t*)data;
188     wms_remove(appdata);
189     }
190    
191     static void
192 harbaum 139 cb_menu_wms_adjust(GtkMenuItem *item, gpointer data) {
193 harbaum 1 appdata_t *appdata = (appdata_t*)data;
194     map_action_set(appdata, MAP_ACTION_BG_ADJUST);
195     }
196    
197     /* ----------- hide objects for performance reasons ----------- */
198    
199     static void
200 harbaum 139 cb_menu_map_hide_sel(GtkMenuItem *item, gpointer data) {
201 harbaum 1 appdata_t *appdata = (appdata_t*)data;
202     map_hide_selected(appdata);
203     }
204    
205     static void
206 harbaum 139 cb_menu_map_show_all(GtkMenuItem *item, gpointer data) {
207 harbaum 1 appdata_t *appdata = (appdata_t*)data;
208     map_show_all(appdata);
209     }
210    
211 harbaum 14 /* ---------------------------------------------------------- */
212 harbaum 1
213 harbaum 188 #if defined(USE_HILDON) && (MAEMO_VERSION_MAJOR == 5)
214     #define MENU_CHECK_ITEM HildonCheckButton
215     #define MENU_CHECK_ITEM_ACTIVE(a) hildon_check_button_get_active(a)
216     #else
217     #define MENU_CHECK_ITEM GtkCheckMenuItem
218     #define MENU_CHECK_ITEM_ACTIVE(a) gtk_check_menu_item_get_active(a)
219 harbaum 1 #endif
220    
221     static void
222 harbaum 188 cb_menu_map_no_icons(MENU_CHECK_ITEM *item, appdata_t *appdata) {
223 harbaum 1
224 harbaum 177 banner_busy_start(appdata, 1, "Redrawing");
225 harbaum 14 map_clear(appdata, MAP_LAYER_OBJECTS_ONLY);
226    
227 harbaum 188 appdata->settings->no_icons = MENU_CHECK_ITEM_ACTIVE(item);
228 harbaum 24
229     map_paint(appdata);
230 harbaum 177 banner_busy_stop(appdata); //"Redrawing"
231 harbaum 24 }
232    
233     static void
234 harbaum 162 cb_menu_style(GtkMenuItem *item, gpointer data) {
235     appdata_t *appdata = (appdata_t*)data;
236    
237     style_select(GTK_WIDGET(appdata->window), appdata);
238     }
239    
240     static void
241 harbaum 139 cb_menu_undo(GtkMenuItem *item, gpointer data) {
242 harbaum 64 appdata_t *appdata = (appdata_t*)data;
243    
244     undo(appdata);
245    
246     // the banner will be displayed from within undo with more details
247     }
248    
249     static void
250 harbaum 139 cb_menu_save_changes(GtkMenuItem *item, gpointer data) {
251 harbaum 14 appdata_t *appdata = (appdata_t*)data;
252    
253 harbaum 1 diff_save(appdata->project, appdata->osm);
254 achadwick 28 banner_show_info(appdata, _("Saved local changes"));
255 harbaum 1 }
256    
257 harbaum 15 static void
258 harbaum 139 cb_menu_undo_changes(GtkMenuItem *item, gpointer data) {
259 harbaum 15 appdata_t *appdata = (appdata_t*)data;
260 harbaum 1
261 harbaum 15 if(!yes_no_f(GTK_WIDGET(appdata->window), NULL, 0, 0,
262 achadwick 28 _("Discard local changes?"),
263 harbaum 69 _("Throw away all the changes you've not "
264     "uploaded yet? This can't be undone.")))
265 harbaum 15 return;
266 achadwick 28
267 harbaum 177 banner_busy_start(appdata, 1, _("Redrawing"));
268 harbaum 15 map_clear(appdata, MAP_LAYER_OBJECTS_ONLY);
269     osm_free(&appdata->icon, appdata->osm);
270     diff_remove(appdata->project);
271 harbaum 175 appdata->osm = osm_parse(appdata->project->path, appdata->project->osm);
272 harbaum 15 map_paint(appdata);
273 harbaum 177 banner_busy_stop(appdata); //"Redrawing"
274 harbaum 15
275 achadwick 28 banner_show_info(appdata, _("Discarded local changes"));
276 harbaum 15 }
277    
278 harbaum 1 static void
279 harbaum 191 cb_menu_osm_relations(GtkMenuItem *item, appdata_t *appdata) {
280     /* list relations of all objects */
281     relation_list(GTK_WIDGET(appdata->window), appdata, NULL);
282 harbaum 76 }
283    
284 harbaum 167 #if !defined(USE_HILDON) || (MAEMO_VERSION_MAJOR < 5)
285 harbaum 76 static void
286 harbaum 188 cb_menu_fullscreen(MENU_CHECK_ITEM *item, gpointer data) {
287 harbaum 1 appdata_t *appdata = (appdata_t *)data;
288    
289 harbaum 188 if(MENU_CHECK_ITEM_ACTIVE(item))
290 harbaum 1 gtk_window_fullscreen(GTK_WINDOW(appdata->window));
291     else
292     gtk_window_unfullscreen(GTK_WINDOW(appdata->window));
293     }
294 harbaum 167 #endif
295 harbaum 1
296     static void
297 harbaum 139 cb_menu_zoomin(GtkMenuItem *item, appdata_t *appdata) {
298 harbaum 1 if(!appdata || !appdata->map) return;
299    
300     map_set_zoom(appdata->map, appdata->map->state->zoom*ZOOM_FACTOR_MENU, TRUE);
301     printf("zoom is now %f\n", appdata->map->state->zoom);
302     }
303    
304     static void
305 harbaum 139 cb_menu_zoomout(GtkMenuItem *item, appdata_t *appdata) {
306 harbaum 1 if(!appdata || !appdata->map) return;
307    
308     map_set_zoom(appdata->map, appdata->map->state->zoom/ZOOM_FACTOR_MENU, TRUE);
309     printf("zoom is now %f\n", appdata->map->state->zoom);
310     }
311    
312     static void
313 harbaum 162 cb_menu_view_detail_inc(GtkMenuItem *item, gpointer data) {
314     appdata_t *appdata = (appdata_t*)data;
315    
316     printf("detail level increase\n");
317     map_detail_increase(appdata->map);
318     }
319    
320     static void
321     cb_menu_view_detail_normal(GtkMenuItem *item, gpointer data) {
322     appdata_t *appdata = (appdata_t*)data;
323    
324     printf("detail level normal\n");
325     map_detail_normal(appdata->map);
326     }
327    
328     static void
329     cb_menu_view_detail_dec(GtkMenuItem *item, gpointer data) {
330     appdata_t *appdata = (appdata_t*)data;
331    
332     printf("detail level decrease\n");
333     map_detail_decrease(appdata->map);
334     }
335    
336     static void
337 harbaum 139 cb_menu_track_import(GtkMenuItem *item, appdata_t *appdata) {
338 harbaum 156 g_assert(appdata->settings);
339 harbaum 1
340     /* open a file selector */
341     GtkWidget *dialog;
342    
343     #ifdef USE_HILDON
344     dialog = hildon_file_chooser_dialog_new(GTK_WINDOW(appdata->window),
345     GTK_FILE_CHOOSER_ACTION_OPEN);
346     #else
347     dialog = gtk_file_chooser_dialog_new (_("Import track file"),
348     GTK_WINDOW(appdata->window),
349     GTK_FILE_CHOOSER_ACTION_OPEN,
350     GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
351     GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
352     NULL);
353     #endif
354    
355 harbaum 156 if(appdata->settings->track_path) {
356     if(!g_file_test(appdata->settings->track_path, G_FILE_TEST_EXISTS)) {
357     char *last_sep = strrchr(appdata->settings->track_path, '/');
358     if(last_sep) {
359     *last_sep = 0; // seperate path from file
360    
361     /* the user just created a new document */
362     gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),
363     appdata->settings->track_path);
364     gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog),
365     last_sep+1);
366    
367     /* restore full filename */
368     *last_sep = '/';
369     }
370     } else
371     gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog),
372     appdata->settings->track_path);
373     }
374    
375 harbaum 1 gtk_widget_show_all (GTK_WIDGET(dialog));
376     if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_FM_OK) {
377     char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
378    
379     /* load a track */
380 harbaum 156 appdata->track.track = track_import(appdata, filename);
381 harbaum 1 if(appdata->track.track) {
382 harbaum 156 if(appdata->settings->track_path) g_free(appdata->settings->track_path);
383     appdata->settings->track_path = g_strdup(filename);
384 harbaum 1 }
385     g_free (filename);
386     }
387    
388     gtk_widget_destroy (dialog);
389     }
390    
391     static void
392 harbaum 188 cb_menu_track_enable_gps(MENU_CHECK_ITEM *item, appdata_t *appdata) {
393     track_enable_gps(appdata, MENU_CHECK_ITEM_ACTIVE(item));
394 harbaum 1 }
395    
396 harbaum 156
397 harbaum 1 static void
398 harbaum 188 cb_menu_track_follow_gps(MENU_CHECK_ITEM *item, appdata_t *appdata) {
399     appdata->settings->follow_gps = MENU_CHECK_ITEM_ACTIVE(item);
400 harbaum 1 }
401    
402 harbaum 156
403 harbaum 1 static void
404 harbaum 156 cb_menu_track_export(GtkMenuItem *item, appdata_t *appdata) {
405     g_assert(appdata->settings);
406    
407     /* open a file selector */
408     GtkWidget *dialog;
409    
410     #ifdef USE_HILDON
411     dialog = hildon_file_chooser_dialog_new(GTK_WINDOW(appdata->window),
412     GTK_FILE_CHOOSER_ACTION_SAVE);
413     #else
414     dialog = gtk_file_chooser_dialog_new(_("Export track file"),
415     GTK_WINDOW(appdata->window),
416     GTK_FILE_CHOOSER_ACTION_SAVE,
417     GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
418     GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
419     NULL);
420     #endif
421    
422     printf("set filename <%s>\n", appdata->settings->track_path);
423    
424     if(appdata->settings->track_path) {
425     if(!g_file_test(appdata->settings->track_path, G_FILE_TEST_EXISTS)) {
426     char *last_sep = strrchr(appdata->settings->track_path, '/');
427     if(last_sep) {
428     *last_sep = 0; // seperate path from file
429    
430     /* the user just created a new document */
431     gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),
432     appdata->settings->track_path);
433     gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog),
434     last_sep+1);
435    
436     /* restore full filename */
437     *last_sep = '/';
438     }
439     } else
440     gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog),
441     appdata->settings->track_path);
442     }
443    
444     if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_FM_OK) {
445     gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
446     if(filename) {
447     printf("export to %s\n", filename);
448    
449     if(!g_file_test(filename, G_FILE_TEST_EXISTS) ||
450     yes_no_f(dialog, appdata, MISC_AGAIN_ID_EXPORT_OVERWRITE,
451     MISC_AGAIN_FLAG_DONT_SAVE_NO,
452     "Overwrite existing file",
453     "The file already exists. "
454     "Do you really want to replace it?")) {
455     if(appdata->settings->track_path)
456     g_free(appdata->settings->track_path);
457     appdata->settings->track_path = g_strdup(filename);
458    
459     track_export(appdata, filename);
460     }
461     }
462     }
463    
464     gtk_widget_destroy (dialog);
465     }
466    
467    
468     static void
469 harbaum 139 cb_menu_track_clear(GtkMenuItem *item, gpointer data) {
470 harbaum 1 appdata_t *appdata = (appdata_t*)data;
471 harbaum 156 track_clear(appdata, appdata->track.track);
472     appdata->track.track = NULL;
473 harbaum 1 }
474    
475 achadwick 55
476    
477    
478     /*
479     * Platform-specific UI tweaks.
480     */
481    
482    
483 achadwick 37 #ifndef USE_HILDON
484     #ifdef PORTRAIT
485 achadwick 55
486     // Portrait mode, for openmoko-like systems
487     #define uispecific_main_menu_new gtk_menu_new
488    
489 achadwick 37 #else
490 achadwick 55
491     // Regular desktop builds
492     #define uispecific_main_menu_new gtk_menu_bar_new
493     #define UISPECIFIC_MAIN_MENU_IS_MENU_BAR
494     #define UISPECIFIC_MENU_HAS_ICONS
495     #define UISPECIFIC_MENU_HAS_ACCELS
496    
497 achadwick 37 #endif //PORTRAIT
498 achadwick 55 #else//USE_HILDON
499    
500     // Maemo/Hildon builds
501     #define uispecific_main_menu_new gtk_menu_new
502    
503 achadwick 37 #endif
504    
505 achadwick 55
506 harbaum 188 #if !defined(USE_HILDON) || (MAEMO_VERSION_MAJOR < 5)
507 achadwick 55 // Half-arsed slapdash common menu item constructor. Let's use GtkBuilder
508     // instead so we have some flexibility.
509    
510     static GtkWidget *
511     menu_append_new_item(appdata_t *appdata,
512     GtkWidget *menu_shell,
513     GtkSignalFunc activate_cb,
514     char *label,
515 achadwick 79 const gchar *icon_name, // stock id or name for icon_load
516     // overridden by label, accels, icon_name
517 achadwick 55 const gchar *accel_path,
518     guint accel_key, // from gdk/gdkkeysyms.h
519     GdkModifierType accel_mods, // e.g. GDK_CONTROL_MASK
520 harbaum 156 gboolean enabled,
521 achadwick 55 gboolean is_check, gboolean check_status)
522     {
523     GtkWidget *item = NULL;
524 achadwick 79 GtkWidget *image = NULL;
525    
526     gboolean stock_item_known = FALSE;
527 achadwick 55 GtkStockItem stock_item;
528 achadwick 79 if (icon_name != NULL) {
529     stock_item_known = gtk_stock_lookup(icon_name, &stock_item);
530 achadwick 55 }
531    
532     // Icons
533     #ifndef UISPECIFIC_MENU_HAS_ICONS
534     item = is_check ? gtk_check_menu_item_new_with_mnemonic (label)
535     : gtk_menu_item_new_with_mnemonic (label);
536     #else
537 achadwick 79 if (is_check) {
538     item = gtk_check_menu_item_new_with_mnemonic (label);
539 achadwick 55 }
540 achadwick 79 else if (!stock_item_known) {
541     GdkPixbuf *pbuf = icon_load(&appdata->icon, icon_name);
542     if (pbuf) {
543     image = gtk_image_new_from_pixbuf(pbuf);
544     }
545     if (image) {
546     item = gtk_image_menu_item_new_with_mnemonic(label);
547     gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
548     }
549     else {
550     item = gtk_menu_item_new_with_mnemonic(label);
551     }
552     }
553 achadwick 55 else {
554     item = gtk_image_menu_item_new_with_mnemonic(label);
555 achadwick 79 image = gtk_image_new_from_stock(icon_name, GTK_ICON_SIZE_MENU);
556     gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
557 achadwick 55 }
558     #endif
559    
560     #ifdef UISPECIFIC_MENU_HAS_ACCELS
561     // Accelerators
562     // Default
563     if (accel_path != NULL) {
564     gtk_menu_item_set_accel_path(GTK_MENU_ITEM(item), accel_path);
565     if (accel_key != 0) {
566     gtk_accel_map_add_entry( accel_path, accel_key, accel_mods );
567     }
568     else if (stock_item_known) {
569     gtk_accel_map_add_entry( accel_path, stock_item.keyval,
570     stock_item.modifier );
571     }
572     }
573     #endif
574    
575     gtk_menu_shell_append(GTK_MENU_SHELL(menu_shell), GTK_WIDGET(item));
576 harbaum 156 gtk_widget_set_sensitive(GTK_WIDGET(item), enabled);
577     if (is_check)
578 achadwick 55 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), check_status);
579 harbaum 156
580 achadwick 55 g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(activate_cb),
581     appdata);
582     return item;
583     }
584    
585 harbaum 1 void menu_create(appdata_t *appdata) {
586     GtkWidget *menu, *item, *submenu;
587 achadwick 37 GtkWidget *about_quit_items_menu;
588 achadwick 55
589     if (g_module_supported()) {
590     printf("*** can use GModule: consider using GtkUIManager / GtkBuilder\n");
591     }
592    
593     menu = uispecific_main_menu_new();
594 achadwick 37 about_quit_items_menu = menu;
595 harbaum 1
596     /* -------------------- Project submenu -------------------- */
597    
598 achadwick 55 GtkAccelGroup *accel_grp = gtk_accel_group_new();
599     item = gtk_menu_item_new_with_mnemonic( _("_Project") );
600 achadwick 37 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
601 harbaum 1 submenu = gtk_menu_new();
602 achadwick 55 gtk_menu_set_accel_group(GTK_MENU(submenu), accel_grp);
603 harbaum 1 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
604 achadwick 55 #ifdef UISPECIFIC_MAIN_MENU_IS_MENU_BAR
605 achadwick 37 about_quit_items_menu = submenu;
606     #endif
607 harbaum 1
608 achadwick 55 menu_append_new_item(
609 harbaum 177 appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_project_open), _("_Open"),
610 achadwick 55 GTK_STOCK_OPEN, "<OSM2Go-Main>/Project/Open",
611 harbaum 156 0, 0, TRUE, FALSE, FALSE
612 achadwick 55 );
613 harbaum 1
614 harbaum 207 #ifndef USE_HILDON
615 harbaum 185 menu_append_new_item(
616     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_project_wizard), _("_Wizard"),
617     GTK_STOCK_NEW, "<OSM2Go-Main>/Project/Wizard",
618 harbaum 156 0, 0, TRUE, FALSE, FALSE
619 achadwick 55 );
620 harbaum 207 #endif
621 harbaum 1
622     /* --------------- view menu ------------------- */
623    
624 achadwick 79 #ifndef UISPECIFIC_MAIN_MENU_IS_MENU_BAR
625 achadwick 37 gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());
626     #endif
627 harbaum 1
628 harbaum 189 appdata->submenu_view = item = gtk_menu_item_new_with_mnemonic( _("_View") );
629 achadwick 37 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
630 harbaum 1 submenu = gtk_menu_new();
631 achadwick 55 gtk_menu_set_accel_group(GTK_MENU(submenu), accel_grp);
632 harbaum 1 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
633    
634 harbaum 167 #if !defined(USE_HILDON) || (MAEMO_VERSION_MAJOR < 5)
635 achadwick 55 appdata->menu_item_view_fullscreen = menu_append_new_item(
636     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_fullscreen), _("_Fullscreen"),
637     GTK_STOCK_FULLSCREEN, "<OSM2Go-Main>/View/Fullscreen",
638 harbaum 156 0, 0, TRUE, TRUE, FALSE
639 achadwick 55 );
640 harbaum 167 #endif
641 harbaum 1
642 achadwick 55 menu_append_new_item(
643     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_zoomin), _("Zoom _in"),
644     GTK_STOCK_ZOOM_IN, "<OSM2Go-Main>/View/ZoomIn",
645 harbaum 156 GDK_comma, GDK_CONTROL_MASK, TRUE, FALSE, FALSE
646 achadwick 55 );
647 harbaum 1
648 achadwick 55 menu_append_new_item(
649     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_zoomout), _("Zoom _out"),
650     GTK_STOCK_ZOOM_OUT, "<OSM2Go-Main>/View/ZoomOut",
651 harbaum 156 GDK_period, GDK_CONTROL_MASK, TRUE, FALSE, FALSE
652 achadwick 55 );
653 harbaum 1
654 harbaum 162 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new());
655    
656     menu_append_new_item(
657     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_view_detail_inc), _("More details"),
658     NULL, "<OSM2Go-Main>/View/DetailInc",
659     GDK_period, GDK_MOD1_MASK, TRUE, FALSE, FALSE
660     );
661    
662     menu_append_new_item(
663     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_view_detail_normal), _("Normal details"),
664     NULL, "<OSM2Go-Main>/View/DetailNormal",
665     0, 0, TRUE, FALSE, FALSE
666     );
667    
668     menu_append_new_item(
669     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_view_detail_dec), _("Less details"),
670     NULL, "<OSM2Go-Main>/View/DetailDec",
671     GDK_comma, GDK_MOD1_MASK, TRUE, FALSE, FALSE
672     );
673    
674 harbaum 188 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new());
675 harbaum 1
676 harbaum 188 appdata->menu_item_map_hide_sel = menu_append_new_item(
677     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_map_hide_sel), _("_Hide selected"),
678 harbaum 189 GTK_STOCK_REMOVE, "<OSM2Go-Main>/View/HideSelected",
679 harbaum 188 0, 0, TRUE, FALSE, FALSE
680     );
681     gtk_widget_set_sensitive(appdata->menu_item_map_hide_sel, FALSE);
682    
683     appdata->menu_item_map_show_all = menu_append_new_item(
684     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_map_show_all), _("_Show all"),
685 harbaum 189 GTK_STOCK_ADD, "<OSM2Go-Main>/View/ShowAll",
686 harbaum 188 0, 0, TRUE, FALSE, FALSE
687     );
688     gtk_widget_set_sensitive(appdata->menu_item_map_show_all, FALSE);
689    
690     gtk_menu_shell_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new());
691    
692     menu_append_new_item(
693     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_style), _("St_yle"),
694 harbaum 189 GTK_STOCK_SELECT_COLOR, "<OSM2Go-Main>/View/Style",
695 harbaum 188 0, 0, TRUE, FALSE, FALSE
696     );
697    
698     gtk_menu_shell_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new());
699    
700     appdata->menu_item_map_no_icons = menu_append_new_item(
701     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_map_no_icons), _("No _icons"),
702 harbaum 189 NULL, "<OSM2Go-Main>/View/NoIcons",
703 harbaum 188 0, 0, TRUE, TRUE, appdata->settings->no_icons
704     );
705    
706    
707     /* -------------------- map submenu -------------------- */
708    
709 harbaum 189 appdata->submenu_map = item = gtk_menu_item_new_with_mnemonic( _("_Map") );
710 achadwick 37 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
711 harbaum 1 submenu = gtk_menu_new();
712 achadwick 55 gtk_menu_set_accel_group(GTK_MENU(submenu), accel_grp);
713 harbaum 1 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
714 harbaum 188
715 harbaum 189 appdata->menu_item_map_upload = menu_append_new_item(
716 harbaum 177 appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_upload), _("_Upload"),
717 harbaum 189 "upload.16", "<OSM2Go-Main>/Map/Upload",
718 harbaum 156 GDK_u, GDK_SHIFT_MASK|GDK_CONTROL_MASK, TRUE, FALSE, FALSE
719 achadwick 55 );
720 harbaum 1
721 achadwick 55 menu_append_new_item(
722 harbaum 177 appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_download), _("_Download"),
723 harbaum 189 "download.16", "<OSM2Go-Main>/Map/Download",
724 harbaum 156 GDK_d, GDK_SHIFT_MASK|GDK_CONTROL_MASK, TRUE, FALSE, FALSE
725 achadwick 55 );
726 harbaum 1
727 achadwick 37 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new());
728 harbaum 1
729 harbaum 64 if(getenv("OSM2GO_UNDO_TEST")) {
730 harbaum 189 appdata->menu_item_map_undo = menu_append_new_item(
731 harbaum 64 appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_undo), _("_Undo"),
732 harbaum 189 GTK_STOCK_UNDO, "<OSM2Go-Main>/Map/Undo",
733 harbaum 156 GDK_z, GDK_CONTROL_MASK, TRUE, FALSE, FALSE
734 harbaum 64 );
735     } else
736     printf("set environment variable OSM2GO_UNDO_TEST to enable undo framework tests\n");
737 harbaum 1
738 harbaum 189 appdata->menu_item_map_save_changes = menu_append_new_item(
739 achadwick 55 appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_save_changes), _("_Save local changes"),
740 harbaum 189 GTK_STOCK_SAVE, "<OSM2Go-Main>/Map/SaveChanges",
741 harbaum 156 GDK_s, GDK_SHIFT_MASK|GDK_CONTROL_MASK, TRUE, FALSE, FALSE
742 achadwick 55 );
743 harbaum 15
744 harbaum 189 appdata->menu_item_map_undo_changes = menu_append_new_item(
745 harbaum 177 appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_undo_changes), _("Disca_rd local changes"),
746 harbaum 189 GTK_STOCK_DELETE, "<OSM2Go-Main>/Map/DiscardChanges",
747 harbaum 156 0, 0, TRUE, FALSE, FALSE
748 achadwick 55 );
749    
750 harbaum 76 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new());
751 harbaum 189 appdata->menu_item_map_relations = menu_append_new_item(
752 harbaum 177 appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_osm_relations), _("_Relations"),
753 harbaum 189 NULL, "<OSM2Go-Main>/Map/Relations",
754 harbaum 156 GDK_r, GDK_SHIFT_MASK|GDK_CONTROL_MASK, TRUE, FALSE, FALSE
755 harbaum 76 );
756    
757 harbaum 1 /* -------------------- wms submenu -------------------- */
758    
759 harbaum 189 appdata->submenu_wms = item = gtk_menu_item_new_with_mnemonic( _("_WMS") );
760 achadwick 37 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
761 harbaum 1 submenu = gtk_menu_new();
762 achadwick 55 gtk_menu_set_accel_group(GTK_MENU(submenu), accel_grp);
763 harbaum 1 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
764    
765 achadwick 55 menu_append_new_item(
766 harbaum 177 appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_wms_import), _("_Import"),
767 achadwick 55 GTK_STOCK_INDEX, "<OSM2Go-Main>/WMS/Import",
768 harbaum 156 0, 0, TRUE, FALSE, FALSE
769 achadwick 55 );
770 harbaum 1
771 achadwick 55 appdata->menu_item_wms_clear = menu_append_new_item(
772     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_wms_clear), _("_Clear"),
773     GTK_STOCK_CLEAR, "<OSM2Go-Main>/WMS/Clear",
774 harbaum 156 0, 0, TRUE, FALSE, FALSE
775 achadwick 55 );
776     gtk_widget_set_sensitive(appdata->menu_item_wms_clear, FALSE);
777 harbaum 1
778 achadwick 55 appdata->menu_item_wms_adjust = menu_append_new_item(
779     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_wms_adjust), _("_Adjust"),
780     NULL, "<OSM2Go-Main>/WMS/Adjust",
781 harbaum 156 0, 0, TRUE, FALSE, FALSE
782 achadwick 55 );
783     gtk_widget_set_sensitive(appdata->menu_item_wms_adjust, FALSE);
784 harbaum 1
785     /* -------------------- track submenu -------------------- */
786    
787 harbaum 189 appdata->track.submenu_track = item =
788     gtk_menu_item_new_with_mnemonic(_("_Track"));
789 achadwick 37 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
790 harbaum 1 submenu = gtk_menu_new();
791 achadwick 55 gtk_menu_set_accel_group(GTK_MENU(submenu), accel_grp);
792 harbaum 1 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
793    
794 harbaum 189 appdata->track.menu_item_track_import = menu_append_new_item(
795 harbaum 177 appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_track_import), _("_Import"),
796 achadwick 55 NULL, "<OSM2Go-Main>/Track/Import",
797 harbaum 156 0, 0, TRUE, FALSE, FALSE
798 achadwick 55 );
799 harbaum 1
800 harbaum 189 appdata->track.menu_item_track_export = menu_append_new_item(
801 harbaum 177 appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_track_export), _("_Export"),
802 achadwick 55 NULL, "<OSM2Go-Main>/Track/Export",
803 harbaum 156 0, 0, FALSE, FALSE, FALSE
804 achadwick 55 );
805 harbaum 1
806 harbaum 189 appdata->track.menu_item_track_clear = menu_append_new_item(
807 achadwick 55 appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_track_clear), _("_Clear"),
808     GTK_STOCK_CLEAR, "<OSM2Go-Main>/Track/Clear",
809 harbaum 156 0, 0, FALSE, FALSE, FALSE
810 achadwick 55 );
811 harbaum 1
812 achadwick 55
813 harbaum 189 appdata->track.menu_item_track_enable_gps = menu_append_new_item(
814 harbaum 156 appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_track_enable_gps),_("_GPS enable"),
815 achadwick 55 NULL, "<OSM2Go-Main>/Track/GPS",
816 harbaum 156 GDK_g, GDK_CONTROL_MASK|GDK_SHIFT_MASK, TRUE, TRUE,
817     appdata->settings->enable_gps
818 achadwick 55 );
819 harbaum 156
820 harbaum 189 appdata->track.menu_item_track_follow_gps = menu_append_new_item(
821 harbaum 156 appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_track_follow_gps), _("GPS follow"),
822     NULL, "<OSM2Go-Main>/Track/Follow",
823     0, 0, appdata->settings->enable_gps, TRUE,
824     appdata->settings->follow_gps
825     );
826 harbaum 1
827     /* ------------------------------------------------------- */
828    
829 achadwick 37 gtk_menu_shell_append(GTK_MENU_SHELL(about_quit_items_menu),
830     gtk_separator_menu_item_new());
831 harbaum 1
832 achadwick 55 menu_append_new_item(
833 harbaum 177 appdata, about_quit_items_menu, GTK_SIGNAL_FUNC(cb_menu_about), _("_About"),
834 achadwick 55 GTK_STOCK_ABOUT, "<OSM2Go-Main>/About",
835 harbaum 156 0, 0, TRUE, FALSE, FALSE
836 achadwick 55 );
837 harbaum 1
838 harbaum 188 #ifndef USE_HILDON
839 achadwick 55 menu_append_new_item(
840     appdata, about_quit_items_menu, GTK_SIGNAL_FUNC(cb_menu_quit), _("_Quit"),
841     GTK_STOCK_QUIT, "<OSM2Go-Main>/Quit",
842 harbaum 156 0, 0, TRUE, FALSE, FALSE
843 achadwick 55 );
844 harbaum 188 #endif
845 harbaum 1
846 achadwick 55 gtk_window_add_accel_group(GTK_WINDOW(appdata->window), accel_grp);
847    
848 harbaum 1 #ifdef USE_HILDON
849     hildon_window_set_menu(appdata->window, GTK_MENU(menu));
850     #else
851 achadwick 37 GtkWidget *menu_bar = menu;
852 harbaum 1
853 achadwick 55 #ifndef UISPECIFIC_MAIN_MENU_IS_MENU_BAR
854 achadwick 37 // we need to make one first
855     menu_bar = gtk_menu_bar_new();
856    
857 harbaum 1 GtkWidget *root_menu = gtk_menu_item_new_with_label (_("Menu"));
858     gtk_widget_show(root_menu);
859    
860     gtk_menu_bar_append(menu_bar, root_menu);
861     gtk_menu_item_set_submenu(GTK_MENU_ITEM (root_menu), menu);
862    
863     gtk_widget_show(menu_bar);
864 achadwick 55 #endif //UISPECIFIC_MAIN_MENU_IS_MENU_BAR
865 achadwick 37
866 harbaum 1 gtk_box_pack_start(GTK_BOX(appdata->vbox), menu_bar, 0, 0, 0);
867 achadwick 37
868     #endif //USE_HILDON
869 harbaum 1 }
870 harbaum 188 #else // !defined(USE_HILDON) || (MAEMO_VERSION_MAJOR < 5)
871 harbaum 1
872 harbaum 188 void submenu_entry(appdata_t *appdata, HildonAppMenu *menu,
873     const char *label, const char *value,
874     GtkSignalFunc activate_cb) {
875    
876     }
877    
878     typedef struct {
879     const char *label, *value;
880     gboolean enabled;
881     gboolean (*toggle)(appdata_t *appdata);
882     gulong offset;
883     GtkSignalFunc activate_cb;
884     } menu_entry_t;
885    
886     static gboolean no_icon_get_toggle(appdata_t *appdata) {
887     if(!appdata) return FALSE;
888     if(!appdata->settings) return FALSE;
889     return appdata->settings->no_icons;
890     }
891    
892 harbaum 190 static gboolean enable_gps_get_toggle(appdata_t *appdata) {
893     if(!appdata) return FALSE;
894 harbaum 192 if(!appdata->settings) return FALSE;
895     return appdata->settings->enable_gps;
896 harbaum 190 }
897    
898     static gboolean follow_gps_get_toggle(appdata_t *appdata) {
899     if(!appdata) return FALSE;
900     if(!appdata->settings) return FALSE;
901     return appdata->settings->follow_gps;
902     }
903    
904 harbaum 188 /* create a HildonAppMenu */
905 harbaum 190 static GtkWidget *app_menu_create(appdata_t *appdata,
906     const menu_entry_t *menu_entries) {
907 harbaum 188 HildonAppMenu *menu = HILDON_APP_MENU(hildon_app_menu_new());
908    
909     while(menu_entries->label) {
910     GtkWidget *button = NULL;
911    
912     if(!menu_entries->toggle) {
913     button = hildon_button_new_with_text(
914     HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH,
915     HILDON_BUTTON_ARRANGEMENT_VERTICAL,
916 harbaum 190 _(menu_entries->label), _(menu_entries->value));
917     g_signal_connect_after(button, "clicked",
918     menu_entries->activate_cb, appdata);
919 harbaum 188 } else {
920     button = hildon_check_button_new(HILDON_SIZE_AUTO);
921     gtk_button_set_label(GTK_BUTTON(button), _(menu_entries->label));
922 harbaum 192 printf("requesting check for %s: %p\n", menu_entries->label,
923     menu_entries->toggle);
924 harbaum 188 hildon_check_button_set_active(HILDON_CHECK_BUTTON(button),
925     menu_entries->toggle(appdata));
926 harbaum 190 g_signal_connect_after(button, "toggled",
927     menu_entries->activate_cb, appdata);
928 harbaum 188 }
929    
930     /* offset to GtkWidget pointer was given -> store pointer */
931     if(menu_entries->offset)
932     *(GtkWidget**)(((void*)appdata)+menu_entries->offset) = button;
933    
934     gtk_widget_set_sensitive(button, menu_entries->enabled);
935    
936     hildon_app_menu_append(menu, GTK_BUTTON(button));
937     menu_entries++;
938     }
939    
940     gtk_widget_show_all(GTK_WIDGET(menu));
941     return GTK_WIDGET(menu);
942     }
943    
944     /* the view submenu */
945     void on_submenu_view_clicked(GtkButton *button, appdata_t *appdata) {
946 harbaum 190 hildon_app_menu_popup(HILDON_APP_MENU(appdata->app_menu_view),
947 harbaum 188 GTK_WINDOW(appdata->window));
948     }
949    
950 harbaum 191 void on_submenu_map_clicked(GtkButton *button, appdata_t *appdata) {
951     hildon_app_menu_popup(HILDON_APP_MENU(appdata->app_menu_map),
952     GTK_WINDOW(appdata->window));
953     }
954    
955 harbaum 188 void on_submenu_wms_clicked(GtkButton *button, appdata_t *appdata) {
956 harbaum 190 hildon_app_menu_popup(HILDON_APP_MENU(appdata->app_menu_wms),
957 harbaum 188 GTK_WINDOW(appdata->window));
958     }
959    
960 harbaum 190 void on_submenu_track_clicked(GtkButton *button, appdata_t *appdata) {
961     hildon_app_menu_popup(HILDON_APP_MENU(appdata->app_menu_track),
962     GTK_WINDOW(appdata->window));
963     }
964    
965 harbaum 188 #define APP_OFFSET(a) offsetof(appdata_t, a)
966     #define SIMPLE_ENTRY(a,b) { a, NULL, TRUE, NULL, 0, G_CALLBACK(b) }
967 harbaum 191 #define ENABLED_ENTRY(a,b,c) { a, NULL, TRUE, NULL, APP_OFFSET(c), G_CALLBACK(b) }
968 harbaum 188 #define DISABLED_ENTRY(a,b,c) { a, NULL, FALSE, NULL, APP_OFFSET(c), G_CALLBACK(b) }
969 harbaum 191 #define TOGGLE_ENTRY(a,b,c) { a, NULL, TRUE, c, 0, G_CALLBACK(b) }
970     #define DISABLED_TOGGLE_ENTRY(a,b,c,d) \
971     { a, NULL, FALSE, c, APP_OFFSET(d), G_CALLBACK(b) }
972     #define ENABLED_TOGGLE_ENTRY(a,b,c,d) \
973     { a, NULL, TRUE, c, APP_OFFSET(d), G_CALLBACK(b) }
974 harbaum 188 #define LAST_ENTRY { NULL, NULL, FALSE, NULL, 0, NULL }
975    
976 harbaum 191 /* -- the view submenu -- */
977 harbaum 188 static const menu_entry_t submenu_view[] = {
978     SIMPLE_ENTRY("Zoom in", cb_menu_zoomin),
979     SIMPLE_ENTRY("Zoom out", cb_menu_zoomout),
980     /* --- */
981     SIMPLE_ENTRY("Style", cb_menu_style),
982     /* --- */
983     SIMPLE_ENTRY("Normal details", cb_menu_view_detail_normal),
984     SIMPLE_ENTRY("More details", cb_menu_view_detail_inc),
985     SIMPLE_ENTRY("Less details", cb_menu_view_detail_dec),
986     /* --- */
987     DISABLED_ENTRY("Hide selected", cb_menu_map_hide_sel, menu_item_map_hide_sel),
988     DISABLED_ENTRY("Show all", cb_menu_map_show_all, menu_item_map_show_all),
989     /* --- */
990 harbaum 190 TOGGLE_ENTRY("No icons", cb_menu_map_no_icons, no_icon_get_toggle),
991 harbaum 188
992     LAST_ENTRY
993     };
994    
995 harbaum 191 /* -- the map submenu -- */
996     static const menu_entry_t submenu_map[] = {
997 harbaum 192 ENABLED_ENTRY("Upload", cb_menu_upload, menu_item_map_upload),
998     SIMPLE_ENTRY("Download", cb_menu_download),
999     ENABLED_ENTRY("Save local changes", cb_menu_save_changes,
1000     menu_item_map_save_changes),
1001     ENABLED_ENTRY("Discard local changes", cb_menu_undo_changes,
1002     menu_item_map_undo_changes),
1003     ENABLED_ENTRY("Relations", cb_menu_osm_relations,
1004     menu_item_map_relations),
1005 harbaum 191
1006     LAST_ENTRY
1007     };
1008    
1009 harbaum 188 /* -- the wms submenu -- */
1010     static const menu_entry_t submenu_wms[] = {
1011     SIMPLE_ENTRY("Import", cb_menu_wms_import),
1012     DISABLED_ENTRY("Clear", cb_menu_wms_clear, menu_item_wms_clear),
1013     DISABLED_ENTRY("Adjust", cb_menu_wms_adjust, menu_item_wms_adjust),
1014    
1015     LAST_ENTRY
1016     };
1017    
1018 harbaum 190 /* -- the track submenu -- */
1019     static const menu_entry_t submenu_track[] = {
1020     ENABLED_ENTRY("Import", cb_menu_track_import, track.menu_item_track_import),
1021     DISABLED_ENTRY("Export", cb_menu_track_export, track.menu_item_track_export),
1022     DISABLED_ENTRY("Clear", cb_menu_track_clear, track.menu_item_track_clear),
1023     ENABLED_TOGGLE_ENTRY("GPS enable", cb_menu_track_enable_gps,
1024     enable_gps_get_toggle, track.menu_item_track_enable_gps),
1025     DISABLED_TOGGLE_ENTRY("GPS follow", cb_menu_track_follow_gps,
1026     follow_gps_get_toggle, track.menu_item_track_follow_gps),
1027 harbaum 188
1028 harbaum 190 LAST_ENTRY
1029     };
1030 harbaum 188
1031    
1032 harbaum 190 /* -- the applications main menu -- */
1033     static const menu_entry_t main_menu[] = {
1034 harbaum 191 SIMPLE_ENTRY("About", cb_menu_about),
1035     SIMPLE_ENTRY("Project", cb_menu_project_open),
1036     ENABLED_ENTRY("View", on_submenu_view_clicked, submenu_view),
1037     ENABLED_ENTRY("Map", on_submenu_map_clicked, submenu_map),
1038     ENABLED_ENTRY("WMS", on_submenu_wms_clicked, submenu_wms),
1039     ENABLED_ENTRY("Track", on_submenu_track_clicked, track.submenu_track),
1040 harbaum 188
1041 harbaum 190 LAST_ENTRY
1042     };
1043 harbaum 188
1044 harbaum 190 void menu_create(appdata_t *appdata) {
1045     HildonAppMenu *menu = HILDON_APP_MENU(hildon_app_menu_new());
1046 harbaum 191
1047 harbaum 190 /* build menu/submenus */
1048     menu = HILDON_APP_MENU(app_menu_create(appdata, main_menu));
1049 harbaum 191 appdata->app_menu_wms = app_menu_create(appdata, submenu_wms);
1050     appdata->app_menu_map = app_menu_create(appdata, submenu_map);
1051     appdata->app_menu_view = app_menu_create(appdata, submenu_view);
1052 harbaum 190 appdata->app_menu_track = app_menu_create(appdata, submenu_track);
1053 harbaum 188
1054 harbaum 191 /* enable/disable some entries according to settings */
1055 harbaum 192 if(appdata && appdata->settings)
1056     gtk_widget_set_sensitive(appdata->track.menu_item_track_follow_gps,
1057     appdata->settings->enable_gps);
1058 harbaum 191
1059 harbaum 190 hildon_window_set_app_menu(HILDON_WINDOW(appdata->window), menu);
1060 harbaum 188 }
1061     #endif
1062    
1063 harbaum 1 /********************* end of menu **********************/
1064    
1065 achadwick 55 #ifdef UISPECIFIC_MENU_HAS_ACCELS
1066     #define ACCELS_FILE "accels"
1067 harbaum 1
1068 achadwick 55 static void menu_accels_load(appdata_t *appdata) {
1069     char *accels_file = g_strdup_printf("%s/" ACCELS_FILE,
1070     appdata->settings->base_path);
1071     gtk_accel_map_load(accels_file);
1072     g_free(accels_file);
1073     }
1074    
1075     static void menu_accels_save(appdata_t *appdata) {
1076     char *accels_file = g_strdup_printf("%s" ACCELS_FILE,
1077     appdata->settings->base_path);
1078     gtk_accel_map_save(accels_file);
1079     g_free(accels_file);
1080     }
1081    
1082     #endif
1083    
1084    
1085 harbaum 1 void cleanup(appdata_t *appdata) {
1086 achadwick 55 #ifdef UISPECIFIC_MENU_HAS_ACCELS
1087     menu_accels_save(appdata);
1088     #endif
1089    
1090 harbaum 1 settings_save(appdata->settings);
1091    
1092     #ifdef USE_HILDON
1093     if(appdata->osso_context)
1094     osso_deinitialize(appdata->osso_context);
1095    
1096     appdata->program = NULL;
1097     #endif
1098    
1099     printf("waiting for gtk to shut down ");
1100    
1101     /* let gtk clean up first */
1102     while(gtk_events_pending()) {
1103     putchar('.');
1104     gtk_main_iteration();
1105     }
1106    
1107     printf(" ok\n");
1108    
1109     /* save project file */
1110     if(appdata->project)
1111     project_save(GTK_WIDGET(appdata->window), appdata->project);
1112    
1113     map_remove_bg_image(appdata->map);
1114    
1115     osm_free(&appdata->icon, appdata->osm);
1116    
1117     curl_global_cleanup();
1118    
1119     josm_presets_free(appdata->presets);
1120    
1121     icon_free_all(&appdata->icon);
1122    
1123     gps_release(appdata);
1124    
1125     settings_free(appdata->settings);
1126    
1127     statusbar_free(appdata->statusbar);
1128    
1129     iconbar_free(appdata->iconbar);
1130    
1131     project_free(appdata->project);
1132    
1133 harbaum 188 if(appdata->menu_item_map_undo)
1134 harbaum 69 undo_free(appdata->undo.state);
1135 harbaum 54
1136 harbaum 1 puts("everything is gone");
1137     }
1138    
1139     void on_window_destroy (GtkWidget *widget, gpointer data) {
1140     appdata_t *appdata = (appdata_t*)data;
1141    
1142     gtk_main_quit();
1143     appdata->window = NULL;
1144     }
1145    
1146     gboolean on_window_key_press(GtkWidget *widget,
1147     GdkEventKey *event, gpointer data) {
1148     appdata_t *appdata = (appdata_t*)data;
1149     int handled = FALSE;
1150    
1151 harbaum 190 // printf("key event with keyval %x\n", event->keyval);
1152    
1153 harbaum 1 // the map handles some keys on its own ...
1154     switch(event->keyval) {
1155    
1156 harbaum 188 #if !defined(USE_HILDON) || (MAEMO_VERSION_MAJOR < 5)
1157 harbaum 22 #ifdef USE_HILDON
1158     /* this is in fact a mapping to GDK_F6 */
1159 harbaum 1 case HILDON_HARDKEY_FULLSCREEN:
1160 harbaum 22 #else
1161     case GDK_F11:
1162     #endif
1163     if(!gtk_check_menu_item_get_active(
1164     GTK_CHECK_MENU_ITEM(appdata->menu_item_view_fullscreen))) {
1165     gtk_window_fullscreen(GTK_WINDOW(appdata->window));
1166 harbaum 1 gtk_check_menu_item_set_active(
1167 harbaum 22 GTK_CHECK_MENU_ITEM(appdata->menu_item_view_fullscreen), TRUE);
1168     } else {
1169 harbaum 1 gtk_window_unfullscreen(GTK_WINDOW(appdata->window));
1170 harbaum 22 gtk_check_menu_item_set_active(
1171     GTK_CHECK_MENU_ITEM(appdata->menu_item_view_fullscreen), FALSE);
1172     }
1173    
1174     handled = TRUE;
1175 harbaum 1 break;
1176 harbaum 188 #endif
1177 harbaum 1 }
1178    
1179     /* forward unprocessed key presses to map */
1180     if(!handled && appdata->project && appdata->osm)
1181     handled = map_key_press_event(appdata, event);
1182    
1183     return handled;
1184     }
1185    
1186     int main(int argc, char *argv[]) {
1187     appdata_t appdata;
1188    
1189     /* init appdata */
1190     memset(&appdata, 0, sizeof(appdata));
1191    
1192     printf("Using locale for %s in %s\n", PACKAGE, LOCALEDIR);
1193    
1194     setlocale(LC_ALL, "");
1195     bindtextdomain(PACKAGE, LOCALEDIR);
1196     bind_textdomain_codeset(PACKAGE, "UTF-8");
1197     textdomain(PACKAGE);
1198    
1199     /* Must initialize libcurl before any threads are started */
1200     curl_global_init(CURL_GLOBAL_ALL);
1201    
1202     g_thread_init(NULL);
1203    
1204 harbaum 118 gtk_init (&argc, &argv);
1205    
1206 harbaum 1 gps_init(&appdata);
1207    
1208     #ifdef USE_HILDON
1209     printf("Installing osso context for \"org.harbaum." PACKAGE "\"\n");
1210     appdata.osso_context = osso_initialize("org.harbaum."PACKAGE,
1211     VERSION, TRUE, NULL);
1212     if(appdata.osso_context == NULL)
1213     fprintf(stderr, "error initiating osso context\n");
1214    
1215     dbus_register(&appdata);
1216     #endif
1217    
1218     #ifdef USE_HILDON
1219     /* Create the hildon program and setup the title */
1220     appdata.program = HILDON_PROGRAM(hildon_program_get_instance());
1221     g_set_application_name("OSM2Go");
1222    
1223     /* Create HildonWindow and set it to HildonProgram */
1224     appdata.window = HILDON_WINDOW(hildon_window_new());
1225     hildon_program_add_window(appdata.program, appdata.window);
1226 harbaum 190
1227     #if MAEMO_VERSION_MAJOR == 5
1228     unsigned long val;
1229     XChangeProperty(GDK_DISPLAY(),
1230     GDK_WINDOW_XID(GTK_WIDGET(appdata.window)->window),
1231     XInternAtom(GDK_DISPLAY(),
1232     "_HILDON_ZOOM_KEY_ATOM",
1233     False), XA_INTEGER, 32,
1234     PropModeReplace, (unsigned char *) &val, 1);
1235     #endif
1236    
1237 harbaum 1 #else
1238     /* Create a Window. */
1239     appdata.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1240     gtk_window_set_title(GTK_WINDOW(appdata.window), "OSM2Go");
1241     /* Set a decent default size for the window. */
1242     gtk_window_set_default_size(GTK_WINDOW(appdata.window),
1243     DEFAULT_WIDTH, DEFAULT_HEIGHT);
1244     gtk_window_set_icon(GTK_WINDOW(appdata.window),
1245     icon_load(&appdata.icon, PACKAGE));
1246     #endif
1247    
1248     g_signal_connect(G_OBJECT(appdata.window), "destroy",
1249     G_CALLBACK(on_window_destroy), &appdata);
1250    
1251     g_signal_connect(G_OBJECT(appdata.window), "key_press_event",
1252     G_CALLBACK(on_window_key_press), &appdata);
1253    
1254 harbaum 14 /* user specific init */
1255     appdata.settings = settings_load();
1256    
1257 harbaum 1 appdata.vbox = gtk_vbox_new(FALSE,0);
1258     menu_create(&appdata);
1259 achadwick 55 #ifdef UISPECIFIC_MENU_HAS_ACCELS
1260     menu_accels_load(&appdata);
1261     #endif
1262 harbaum 1
1263     /* ----------------------- setup main window ---------------- */
1264    
1265     GtkWidget *hbox = gtk_hbox_new(FALSE,0);
1266     GtkWidget *vbox = gtk_vbox_new(FALSE,0);
1267    
1268     #ifdef PORTRAIT
1269     gtk_box_pack_start(GTK_BOX(vbox), iconbar_new(&appdata), FALSE, FALSE, 0);
1270     #endif
1271 harbaum 22
1272     /* generate main map view */
1273     GtkWidget *map = map_new(&appdata);
1274     if(!map) {
1275     cleanup(&appdata);
1276     return -1;
1277     }
1278    
1279 harbaum 188 #if 0 // another test overlay
1280     {
1281     GtkWidget *fixed = gtk_fixed_new();
1282    
1283     gtk_fixed_put(GTK_FIXED(fixed), gtk_label_new("Nase"), 0,0);
1284     gtk_fixed_put(GTK_FIXED(fixed), map, 0,0);
1285    
1286     gtk_box_pack_start(GTK_BOX(vbox), fixed, TRUE, TRUE, 0);
1287     }
1288     #else
1289 harbaum 22 gtk_box_pack_start(GTK_BOX(vbox), map, TRUE, TRUE, 0);
1290 harbaum 188 #endif
1291    
1292 harbaum 195 #ifdef ZOOM_BUTTONS
1293     GtkWidget *zhbox = gtk_hbox_new(FALSE, 0);
1294    
1295     gtk_box_pack_start_defaults(GTK_BOX(zhbox), statusbar_new(&appdata));
1296    
1297     /* ---- add zoom in button right of statusbar ---- */
1298     appdata.btn_zoom_in = gtk_button_new();
1299     gtk_button_set_image(GTK_BUTTON(appdata.btn_zoom_in),
1300     gtk_image_new_from_stock(GTK_STOCK_ZOOM_IN, GTK_ICON_SIZE_MENU));
1301     g_signal_connect(appdata.btn_zoom_in, "clicked", G_CALLBACK(cb_menu_zoomin), &appdata);
1302     gtk_box_pack_start(GTK_BOX(zhbox), appdata.btn_zoom_in, FALSE, FALSE, 0);
1303    
1304     /* ---- add zoom out button right of statusbar ---- */
1305     appdata.btn_zoom_out = gtk_button_new();
1306     gtk_button_set_image(GTK_BUTTON(appdata.btn_zoom_out),
1307     gtk_image_new_from_stock(GTK_STOCK_ZOOM_OUT, GTK_ICON_SIZE_MENU));
1308     g_signal_connect(appdata.btn_zoom_out, "clicked", G_CALLBACK(cb_menu_zoomout), &appdata);
1309     gtk_box_pack_start(GTK_BOX(zhbox), appdata.btn_zoom_out, FALSE, FALSE, 0);
1310    
1311    
1312     gtk_box_pack_start(GTK_BOX(vbox), zhbox, FALSE, FALSE, 0);
1313     #else
1314 harbaum 1 gtk_box_pack_start(GTK_BOX(vbox), statusbar_new(&appdata), FALSE, FALSE, 0);
1315 harbaum 195 #endif
1316 harbaum 1
1317     #ifndef PORTRAIT
1318     gtk_box_pack_start(GTK_BOX(hbox), iconbar_new(&appdata), FALSE, FALSE, 0);
1319     #endif
1320     gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
1321    
1322     gtk_box_pack_start(GTK_BOX(appdata.vbox), hbox, TRUE, TRUE, 0);
1323    
1324     gtk_container_add(GTK_CONTAINER(appdata.window), appdata.vbox);
1325    
1326     gtk_widget_show_all(GTK_WIDGET(appdata.window));
1327    
1328     appdata.presets = josm_presets_load();
1329    
1330     /* let gtk do its thing before loading the data, */
1331     /* so the user sees something */
1332 harbaum 179 while(gtk_events_pending())
1333 harbaum 1 gtk_main_iteration();
1334    
1335     /* load project if one is specified in the settings */
1336     if(appdata.settings->project)
1337     project_load(&appdata, appdata.settings->project);
1338    
1339 harbaum 4 main_ui_enable(&appdata);
1340 harbaum 1
1341 harbaum 156 /* start GPS if enabled by config */
1342     if(appdata.settings && appdata.settings->enable_gps)
1343     track_enable_gps(&appdata, TRUE);
1344    
1345 harbaum 179 /* again let the ui do its thing */
1346     while(gtk_events_pending())
1347     gtk_main_iteration();
1348    
1349 harbaum 188 #if 0 // test overlay
1350     {
1351     GtkWidget *overlay = gtk_window_new(GTK_WINDOW_POPUP);
1352     gtk_window_set_default_size(GTK_WINDOW(overlay), 40, 20);
1353     gtk_window_set_transient_for(GTK_WINDOW(overlay), GTK_WINDOW(appdata.window));
1354     gtk_window_set_keep_above(GTK_WINDOW(overlay), TRUE);
1355     gtk_window_set_destroy_with_parent(GTK_WINDOW(overlay), TRUE);
1356     gtk_window_set_position(GTK_WINDOW(overlay), GTK_WIN_POS_CENTER_ON_PARENT);
1357     gtk_window_set_decorated(GTK_WINDOW(overlay), TRUE);
1358    
1359     /* add some zoom buttons for testing */
1360     GtkWidget *hbox = gtk_hbox_new(TRUE, 0);
1361     gtk_box_pack_start_defaults(GTK_BOX(hbox), gtk_button_new_with_label("+"));
1362     gtk_box_pack_start_defaults(GTK_BOX(hbox), gtk_button_new_with_label("-"));
1363     gtk_container_add(GTK_CONTAINER(overlay), hbox);
1364    
1365     gtk_widget_show_all(overlay);
1366     }
1367     #endif
1368    
1369 harbaum 179 /* start to interact with the user now that the gui is running */
1370     if(appdata.settings->first_run_demo) {
1371     messagef(GTK_WIDGET(appdata.window), _("Welcome to OSM2Go"),
1372     _("This is the first time you run OSM2Go. "
1373     "A demo project has been loaded to get you "
1374     "started. You can play around with this demo as much "
1375     "as you like. However, you cannot upload or download "
1376     "the demo project.\n\n"
1377     "In order to start working on real data you'll have "
1378     "to setup a new project and enter your OSM user name "
1379     "and password. You'll then be able to download the "
1380     "latest data from OSM and upload your changes into "
1381     "the OSM main database."
1382     ));
1383     }
1384    
1385 harbaum 1 /* ------------ jump into main loop ---------------- */
1386     gtk_main();
1387    
1388 harbaum 4 puts("gtk_main() left");
1389    
1390 harbaum 1 track_save(appdata.project, appdata.track.track);
1391 harbaum 118 track_clear(&appdata, appdata.track.track);
1392 harbaum 156 appdata.track.track = NULL;
1393 harbaum 1
1394     /* save a diff if there are dirty entries */
1395     diff_save(appdata.project, appdata.osm);
1396    
1397     cleanup(&appdata);
1398    
1399     return 0;
1400     }
1401 achadwick 55
1402     // vim:et:ts=8:sw=2:sts=2:ai