Contents of /trunk/src/main.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 140 - (hide annotations)
Sun Mar 22 20:25:14 2009 UTC (15 years, 2 months ago) by harbaum
File MIME type: text/plain
File size: 30857 byte(s)
Fixed issues in Maemo about box
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     #include "appdata.h"
27 achadwick 28 #include "banner.h"
28 harbaum 1
29     /* disable/enable main screen control dependant on presence of open project */
30 harbaum 4 static void main_ui_enable(appdata_t *appdata) {
31     gboolean project_valid = (appdata->project != NULL);
32     gboolean osm_valid = (appdata->osm != NULL);
33 harbaum 1
34     /* cancel any action in progress */
35     if(GTK_WIDGET_FLAGS(appdata->iconbar->cancel) & GTK_SENSITIVE)
36     map_action_cancel(appdata);
37    
38     /* ---- set project name as window title ----- */
39     #ifndef USE_HILDON
40     char *str = NULL;
41 harbaum 4 if(project_valid)
42 harbaum 1 str = g_strdup_printf("OSM2Go - %s", appdata->project->name);
43     else
44     str = g_strdup_printf("OSM2Go");
45    
46     gtk_window_set_title(GTK_WINDOW(appdata->window), str);
47     g_free(str);
48     #else
49 harbaum 4 if(project_valid)
50 harbaum 1 gtk_window_set_title(GTK_WINDOW(appdata->window), appdata->project->name);
51     else
52     gtk_window_set_title(GTK_WINDOW(appdata->window), "");
53     #endif
54    
55     if(appdata->iconbar && appdata->iconbar->toolbar)
56 harbaum 4 gtk_widget_set_sensitive(appdata->iconbar->toolbar, osm_valid);
57 harbaum 1
58     /* disable all menu entries related to map */
59 harbaum 4 gtk_widget_set_sensitive(appdata->menu_osm, project_valid);
60     gtk_widget_set_sensitive(appdata->menu_item_osm_upload, osm_valid);
61 harbaum 67 if(appdata->menu_item_osm_undo)
62     gtk_widget_set_sensitive(appdata->menu_item_osm_undo, osm_valid);
63 harbaum 64 gtk_widget_set_sensitive(appdata->menu_item_osm_save_changes, osm_valid);
64 harbaum 15 gtk_widget_set_sensitive(appdata->menu_item_osm_undo_changes, osm_valid);
65 harbaum 4 gtk_widget_set_sensitive(appdata->track.menu_track, osm_valid);
66     gtk_widget_set_sensitive(appdata->menu_view, osm_valid);
67     gtk_widget_set_sensitive(appdata->menu_wms, osm_valid);
68     gtk_widget_set_sensitive(appdata->menu_map, osm_valid);
69     gtk_widget_set_sensitive(appdata->menu_item_project_close, project_valid);
70 harbaum 1
71 harbaum 4 if(!project_valid)
72 achadwick 6 statusbar_set(appdata, _("Please load or create a project"), FALSE);
73 harbaum 1 }
74    
75     /******************** begin of menu *********************/
76    
77     static void
78 harbaum 139 cb_menu_project_open(GtkMenuItem *item, gpointer data) {
79 harbaum 1 appdata_t *appdata = (appdata_t*)data;
80     project_load(appdata, NULL);
81 harbaum 4 main_ui_enable(appdata);
82 harbaum 1 }
83    
84     static void
85 harbaum 139 cb_menu_project_close(GtkMenuItem *item, gpointer data) {
86 harbaum 1 appdata_t *appdata = (appdata_t*)data;
87     project_close(appdata);
88 harbaum 4 main_ui_enable(appdata);
89 harbaum 1 }
90    
91     static void
92 harbaum 139 cb_menu_about(GtkMenuItem *item, gpointer data) {
93     appdata_t *appdata = (appdata_t*)data;
94 harbaum 1
95     const gchar *authors[] = {
96     "Till Harbaum <till@harbaum.org>",
97 achadwick 28 "Andrew Chadwick <andrewc-osm2go@piffle.org>",
98 harbaum 1 NULL };
99    
100 harbaum 139 const gchar *artists[] = {
101 harbaum 140 #ifdef USE_HILDON
102     /* cyrillic doesn't seem to work on hildon */
103     "Andrew Zhilin <drew.zhilin@gmail.com>",
104     #else
105 harbaum 139 "Андрей Жилин <drew.zhilin@gmail.com>",
106 harbaum 140 #endif
107 harbaum 139 NULL };
108 harbaum 1
109 harbaum 139 gtk_show_about_dialog(GTK_WINDOW(appdata->window),
110 harbaum 140 "name", "OSM2Go",
111 harbaum 139 "version", VERSION,
112     "copyright", _("Copyright 2008-2009"),
113     "authors", authors,
114     "artists", artists,
115     "website", _("http://www.harbaum.org/till/maemo"),
116     "comments", _("Mobile OSM Editor"),
117     NULL);
118 harbaum 1 }
119    
120     void on_window_destroy (GtkWidget *widget, gpointer data);
121    
122     static void
123 harbaum 139 cb_menu_quit(GtkMenuItem *item, gpointer data) {
124 harbaum 1 appdata_t *appdata = (appdata_t*)data;
125     gtk_widget_destroy(GTK_WIDGET(appdata->window));
126     }
127    
128     static void
129 harbaum 139 cb_menu_upload(GtkMenuItem *item, gpointer data) {
130 harbaum 1 appdata_t *appdata = (appdata_t*)data;
131     if(!appdata->osm || !appdata->project) return;
132    
133     osm_upload(appdata, appdata->osm, appdata->project);
134     }
135    
136     static void
137 harbaum 139 cb_menu_download(GtkMenuItem *item, gpointer data) {
138 harbaum 1 appdata_t *appdata = (appdata_t*)data;
139 harbaum 4 if(!appdata->project) return;
140 harbaum 1
141 harbaum 4 /* if we have valid osm data loaded: save state first */
142     if(appdata->osm) {
143     /* redraw the entire map by destroying all map items and redrawing them */
144     diff_save(appdata->project, appdata->osm);
145     map_clear(appdata, MAP_LAYER_OBJECTS_ONLY);
146     osm_free(&appdata->icon, appdata->osm);
147 harbaum 1
148 harbaum 4 appdata->osm = NULL;
149     }
150    
151 harbaum 1 // download
152 harbaum 4 if(osm_download(GTK_WIDGET(appdata->window), appdata->project)) {
153 achadwick 36 banner_busy_start(appdata, 1, "Redrawing...");
154 harbaum 4 appdata->osm = osm_parse(appdata->project->osm);
155     diff_restore(appdata, appdata->project, appdata->osm);
156     map_paint(appdata);
157 achadwick 36 banner_busy_stop(appdata); //"Redrawing..."
158 harbaum 4 }
159 harbaum 1
160 harbaum 4 main_ui_enable(appdata);
161 harbaum 1 }
162    
163     static void
164 harbaum 139 cb_menu_wms_import(GtkMenuItem *item, gpointer data) {
165 harbaum 1 appdata_t *appdata = (appdata_t*)data;
166     wms_import(appdata);
167     }
168    
169     static void
170 harbaum 139 cb_menu_wms_clear(GtkMenuItem *item, gpointer data) {
171 harbaum 1 appdata_t *appdata = (appdata_t*)data;
172     wms_remove(appdata);
173     }
174    
175     static void
176 harbaum 139 cb_menu_wms_adjust(GtkMenuItem *item, gpointer data) {
177 harbaum 1 appdata_t *appdata = (appdata_t*)data;
178     map_action_set(appdata, MAP_ACTION_BG_ADJUST);
179     }
180    
181     /* ----------- hide objects for performance reasons ----------- */
182    
183     static void
184 harbaum 139 cb_menu_map_hide_sel(GtkMenuItem *item, gpointer data) {
185 harbaum 1 appdata_t *appdata = (appdata_t*)data;
186     map_hide_selected(appdata);
187     }
188    
189     static void
190 harbaum 139 cb_menu_map_show_all(GtkMenuItem *item, gpointer data) {
191 harbaum 1 appdata_t *appdata = (appdata_t*)data;
192     map_show_all(appdata);
193     }
194    
195 harbaum 14 /* ---------------------------------------------------------- */
196 harbaum 1
197     #if 1 // mainly for testing
198     static void
199 harbaum 139 cb_menu_redraw(GtkMenuItem *item, gpointer data) {
200 harbaum 1 appdata_t *appdata = (appdata_t*)data;
201    
202     /* redraw the entire map by destroying all map items and redrawing them */
203 achadwick 28 banner_busy_start(appdata, 1, "Redrawing...");
204 harbaum 1 track_save(appdata->project, appdata->track.track);
205     diff_save(appdata->project, appdata->osm);
206     map_clear(appdata, MAP_LAYER_ALL);
207     osm_free(&appdata->icon, appdata->osm);
208    
209     appdata->osm = osm_parse(appdata->project->osm);
210     diff_restore(appdata, appdata->project, appdata->osm);
211     map_paint(appdata);
212    
213     appdata->track.track = track_restore(appdata, appdata->project);
214     if(appdata->track.track)
215     map_track_draw(appdata->map, appdata->track.track);
216    
217     wms_load(appdata);
218 achadwick 28 banner_busy_stop(appdata); //"Redrawing..."
219 harbaum 1 }
220     #endif
221    
222     static void
223 harbaum 139 cb_menu_style(GtkMenuItem *item, gpointer data) {
224 harbaum 1 appdata_t *appdata = (appdata_t*)data;
225    
226     style_select(GTK_WIDGET(appdata->window), appdata);
227     }
228    
229     static void
230 harbaum 139 cb_menu_map_no_icons(GtkCheckMenuItem *item, gpointer data) {
231 harbaum 1 appdata_t *appdata = (appdata_t*)data;
232    
233 achadwick 28 banner_busy_start(appdata, 1, "Redrawing...");
234 harbaum 14 map_clear(appdata, MAP_LAYER_OBJECTS_ONLY);
235 harbaum 139 appdata->settings->no_icons = gtk_check_menu_item_get_active(item);
236 harbaum 14 map_paint(appdata);
237 achadwick 28 banner_busy_stop(appdata); //"Redrawing..."
238 harbaum 14 }
239    
240     static void
241 harbaum 139 cb_menu_map_no_antialias(GtkCheckMenuItem *item, gpointer data) {
242 harbaum 24 appdata_t *appdata = (appdata_t*)data;
243    
244 achadwick 28 banner_busy_start(appdata, 1, "Redrawing...");
245 harbaum 24 map_clear(appdata, MAP_LAYER_OBJECTS_ONLY);
246 harbaum 139 appdata->settings->no_antialias = gtk_check_menu_item_get_active(item);
247 harbaum 24 map_paint(appdata);
248 achadwick 28 banner_busy_stop(appdata); //"Redrawing..."
249 harbaum 24 }
250    
251     static void
252 harbaum 139 cb_menu_undo(GtkMenuItem *item, gpointer data) {
253 harbaum 64 appdata_t *appdata = (appdata_t*)data;
254    
255     undo(appdata);
256    
257     // the banner will be displayed from within undo with more details
258     }
259    
260     static void
261 harbaum 139 cb_menu_save_changes(GtkMenuItem *item, gpointer data) {
262 harbaum 14 appdata_t *appdata = (appdata_t*)data;
263    
264 harbaum 1 diff_save(appdata->project, appdata->osm);
265 achadwick 28 banner_show_info(appdata, _("Saved local changes"));
266 harbaum 1 }
267    
268 harbaum 15 static void
269 harbaum 139 cb_menu_undo_changes(GtkMenuItem *item, gpointer data) {
270 harbaum 15 appdata_t *appdata = (appdata_t*)data;
271 harbaum 1
272 harbaum 15 if(!yes_no_f(GTK_WIDGET(appdata->window), NULL, 0, 0,
273 achadwick 28 _("Discard local changes?"),
274 harbaum 69 _("Throw away all the changes you've not "
275     "uploaded yet? This can't be undone.")))
276 harbaum 15 return;
277 achadwick 28
278     banner_busy_start(appdata, 1, _("Redrawing..."));
279 harbaum 15 map_clear(appdata, MAP_LAYER_OBJECTS_ONLY);
280     osm_free(&appdata->icon, appdata->osm);
281     diff_remove(appdata->project);
282     appdata->osm = osm_parse(appdata->project->osm);
283     map_paint(appdata);
284 achadwick 28 banner_busy_stop(appdata); //"Redrawing..."
285 harbaum 15
286 achadwick 28 banner_show_info(appdata, _("Discarded local changes"));
287 harbaum 15 }
288    
289 harbaum 1 static void
290 harbaum 139 cb_menu_osm_relations(GtkMenuItem *item, gpointer data) {
291 harbaum 76 relation_list((appdata_t*)data);
292     }
293    
294     static void
295 harbaum 139 cb_menu_fullscreen(GtkCheckMenuItem *item, gpointer data) {
296 harbaum 1 appdata_t *appdata = (appdata_t *)data;
297    
298 harbaum 139 if(gtk_check_menu_item_get_active(item))
299 harbaum 1 gtk_window_fullscreen(GTK_WINDOW(appdata->window));
300     else
301     gtk_window_unfullscreen(GTK_WINDOW(appdata->window));
302     }
303    
304     static void
305 harbaum 139 cb_menu_zoomin(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 139 cb_menu_zoomout(GtkMenuItem *item, appdata_t *appdata) {
314 harbaum 1 if(!appdata || !appdata->map) return;
315    
316     map_set_zoom(appdata->map, appdata->map->state->zoom/ZOOM_FACTOR_MENU, TRUE);
317     printf("zoom is now %f\n", appdata->map->state->zoom);
318     }
319    
320     static void
321 harbaum 139 cb_menu_track_import(GtkMenuItem *item, appdata_t *appdata) {
322 harbaum 1
323     /* open a file selector */
324     GtkWidget *dialog;
325    
326     #ifdef USE_HILDON
327     dialog = hildon_file_chooser_dialog_new(GTK_WINDOW(appdata->window),
328     GTK_FILE_CHOOSER_ACTION_OPEN);
329     #else
330     dialog = gtk_file_chooser_dialog_new (_("Import track file"),
331     GTK_WINDOW(appdata->window),
332     GTK_FILE_CHOOSER_ACTION_OPEN,
333     GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
334     GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
335     NULL);
336     #endif
337    
338     /* use path if one is present */
339     if(appdata->track.import_path)
340     gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),
341     appdata->track.import_path);
342    
343     gtk_widget_show_all (GTK_WIDGET(dialog));
344     if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_FM_OK) {
345     char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
346    
347     /* load a track */
348     track_do(appdata, TRACK_IMPORT, filename);
349     if(appdata->track.track) {
350    
351     /* save path if gpx was successfully loaded */
352     char *r = strrchr(filename, '/');
353    
354     /* there is a delimiter, use everything left of it as path */
355     if(r) {
356     *r = 0;
357     if(appdata->track.import_path) g_free(appdata->track.import_path);
358     appdata->track.import_path = g_strdup(filename);
359     /* restore path ... just in case ... */
360     *r = '/';
361     }
362     }
363     g_free (filename);
364     }
365    
366     gtk_widget_destroy (dialog);
367     }
368    
369     static void
370 harbaum 139 cb_menu_track_gps(GtkMenuItem *item, gpointer data) {
371 harbaum 1 appdata_t *appdata = (appdata_t*)data;
372    
373     if(gtk_check_menu_item_get_active(
374     GTK_CHECK_MENU_ITEM(appdata->track.menu_item_gps))) {
375     track_do(appdata, TRACK_GPS, NULL);
376     } else {
377     track_do(appdata, TRACK_NONE, NULL);
378     }
379     }
380    
381     static void
382 harbaum 139 cb_menu_track_export(GtkMenuItem *item, gpointer data) {
383 harbaum 1 appdata_t *appdata = (appdata_t*)data;
384     messagef(GTK_WIDGET(appdata->window), _("NIY"),
385     _("Track export is not yet supported."));
386     }
387    
388     static void
389 harbaum 139 cb_menu_track_clear(GtkMenuItem *item, gpointer data) {
390 harbaum 1 appdata_t *appdata = (appdata_t*)data;
391     track_do(appdata, TRACK_NONE, NULL);
392     }
393    
394 achadwick 55
395    
396    
397     /*
398     * Platform-specific UI tweaks.
399     */
400    
401    
402 achadwick 37 #ifndef USE_HILDON
403     #ifdef PORTRAIT
404 achadwick 55
405     // Portrait mode, for openmoko-like systems
406     #define uispecific_main_menu_new gtk_menu_new
407    
408 achadwick 37 #else
409 achadwick 55
410     // Regular desktop builds
411     #define uispecific_main_menu_new gtk_menu_bar_new
412     #define UISPECIFIC_MAIN_MENU_IS_MENU_BAR
413     #define UISPECIFIC_MENU_HAS_ICONS
414     #define UISPECIFIC_MENU_HAS_ACCELS
415    
416 achadwick 37 #endif //PORTRAIT
417 achadwick 55 #else//USE_HILDON
418    
419     // Maemo/Hildon builds
420     #define uispecific_main_menu_new gtk_menu_new
421    
422 achadwick 37 #endif
423    
424 achadwick 55
425    
426     // Half-arsed slapdash common menu item constructor. Let's use GtkBuilder
427     // instead so we have some flexibility.
428    
429     static GtkWidget *
430     menu_append_new_item(appdata_t *appdata,
431     GtkWidget *menu_shell,
432     GtkSignalFunc activate_cb,
433     char *label,
434 achadwick 79 const gchar *icon_name, // stock id or name for icon_load
435     // overridden by label, accels, icon_name
436 achadwick 55 const gchar *accel_path,
437     guint accel_key, // from gdk/gdkkeysyms.h
438     GdkModifierType accel_mods, // e.g. GDK_CONTROL_MASK
439     gboolean is_check, gboolean check_status)
440     {
441     GtkWidget *item = NULL;
442 achadwick 79 GtkWidget *image = NULL;
443    
444     gboolean stock_item_known = FALSE;
445 achadwick 55 GtkStockItem stock_item;
446 achadwick 79 if (icon_name != NULL) {
447     stock_item_known = gtk_stock_lookup(icon_name, &stock_item);
448 achadwick 55 }
449    
450     // Icons
451     #ifndef UISPECIFIC_MENU_HAS_ICONS
452     item = is_check ? gtk_check_menu_item_new_with_mnemonic (label)
453     : gtk_menu_item_new_with_mnemonic (label);
454     #else
455 achadwick 79 if (is_check) {
456     item = gtk_check_menu_item_new_with_mnemonic (label);
457 achadwick 55 }
458 achadwick 79 else if (!stock_item_known) {
459     GdkPixbuf *pbuf = icon_load(&appdata->icon, icon_name);
460     if (pbuf) {
461     image = gtk_image_new_from_pixbuf(pbuf);
462     }
463     if (image) {
464     item = gtk_image_menu_item_new_with_mnemonic(label);
465     gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
466     }
467     else {
468     item = gtk_menu_item_new_with_mnemonic(label);
469     }
470     }
471 achadwick 55 else {
472     item = gtk_image_menu_item_new_with_mnemonic(label);
473 achadwick 79 image = gtk_image_new_from_stock(icon_name, GTK_ICON_SIZE_MENU);
474     gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
475 achadwick 55 }
476     #endif
477    
478     #ifdef UISPECIFIC_MENU_HAS_ACCELS
479     // Accelerators
480     // Default
481     if (accel_path != NULL) {
482     gtk_menu_item_set_accel_path(GTK_MENU_ITEM(item), accel_path);
483     if (accel_key != 0) {
484     gtk_accel_map_add_entry( accel_path, accel_key, accel_mods );
485     }
486     else if (stock_item_known) {
487     gtk_accel_map_add_entry( accel_path, stock_item.keyval,
488     stock_item.modifier );
489     }
490     }
491     #endif
492    
493     gtk_menu_shell_append(GTK_MENU_SHELL(menu_shell), GTK_WIDGET(item));
494     if (is_check) {
495     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), check_status);
496     }
497     g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(activate_cb),
498     appdata);
499     return item;
500     }
501    
502    
503 harbaum 1 void menu_create(appdata_t *appdata) {
504     GtkWidget *menu, *item, *submenu;
505 achadwick 37 GtkWidget *about_quit_items_menu;
506 achadwick 55
507     if (g_module_supported()) {
508     printf("*** can use GModule: consider using GtkUIManager / GtkBuilder\n");
509     }
510    
511     menu = uispecific_main_menu_new();
512 achadwick 37 about_quit_items_menu = menu;
513 harbaum 1
514     /* -------------------- Project submenu -------------------- */
515    
516 achadwick 55 GtkAccelGroup *accel_grp = gtk_accel_group_new();
517     item = gtk_menu_item_new_with_mnemonic( _("_Project") );
518 achadwick 37 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
519 harbaum 1 submenu = gtk_menu_new();
520 achadwick 55 gtk_menu_set_accel_group(GTK_MENU(submenu), accel_grp);
521 harbaum 1 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
522 achadwick 55 #ifdef UISPECIFIC_MAIN_MENU_IS_MENU_BAR
523 achadwick 37 about_quit_items_menu = submenu;
524     #endif
525 harbaum 1
526 achadwick 55 menu_append_new_item(
527     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_project_open), _("_Open..."),
528     GTK_STOCK_OPEN, "<OSM2Go-Main>/Project/Open",
529     0, 0, FALSE, FALSE
530     );
531 harbaum 1
532 achadwick 55 appdata->menu_item_project_close = menu_append_new_item(
533     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_project_close), _("_Close"),
534     GTK_STOCK_CLOSE, "<OSM2Go-Main>/Project/Close",
535     0, 0, FALSE, FALSE
536     );
537 harbaum 1
538     /* --------------- view menu ------------------- */
539    
540 achadwick 79 #ifndef UISPECIFIC_MAIN_MENU_IS_MENU_BAR
541 achadwick 37 gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());
542     #endif
543 harbaum 1
544 achadwick 55 appdata->menu_view = item = gtk_menu_item_new_with_mnemonic( _("_View") );
545 achadwick 37 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
546 harbaum 1 submenu = gtk_menu_new();
547 achadwick 55 gtk_menu_set_accel_group(GTK_MENU(submenu), accel_grp);
548 harbaum 1 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
549    
550 achadwick 55 appdata->menu_item_view_fullscreen = menu_append_new_item(
551     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_fullscreen), _("_Fullscreen"),
552     GTK_STOCK_FULLSCREEN, "<OSM2Go-Main>/View/Fullscreen",
553     0, 0, TRUE, FALSE
554     );
555 harbaum 1
556 achadwick 55 menu_append_new_item(
557     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_zoomin), _("Zoom _in"),
558     GTK_STOCK_ZOOM_IN, "<OSM2Go-Main>/View/ZoomIn",
559     GDK_comma, GDK_CONTROL_MASK, FALSE, FALSE
560     );
561 harbaum 1
562 achadwick 55 menu_append_new_item(
563     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_zoomout), _("Zoom _out"),
564     GTK_STOCK_ZOOM_OUT, "<OSM2Go-Main>/View/ZoomOut",
565     GDK_period, GDK_CONTROL_MASK, FALSE, FALSE
566     );
567 harbaum 1
568     /* -------------------- OSM submenu -------------------- */
569    
570 achadwick 55 appdata->menu_osm = item = gtk_menu_item_new_with_mnemonic( _("_OSM") );
571 achadwick 37 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
572 harbaum 1 submenu = gtk_menu_new();
573 achadwick 55 gtk_menu_set_accel_group(GTK_MENU(submenu), accel_grp);
574 harbaum 1 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
575    
576 achadwick 55 appdata->menu_item_osm_upload = menu_append_new_item(
577     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_upload), _("_Upload..."),
578 achadwick 79 "upload.16", "<OSM2Go-Main>/OSM/Upload",
579 achadwick 55 GDK_u, GDK_SHIFT_MASK|GDK_CONTROL_MASK, FALSE, FALSE
580     );
581 harbaum 1
582 achadwick 55 menu_append_new_item(
583     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_download), _("_Download..."),
584 achadwick 79 "download.16", "<OSM2Go-Main>/OSM/Download",
585 achadwick 55 GDK_d, GDK_SHIFT_MASK|GDK_CONTROL_MASK, FALSE, FALSE
586     );
587 harbaum 1
588 achadwick 37 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new());
589 harbaum 1
590 harbaum 64 if(getenv("OSM2GO_UNDO_TEST")) {
591     appdata->menu_item_osm_undo = menu_append_new_item(
592     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_undo), _("_Undo"),
593     GTK_STOCK_UNDO, "<OSM2Go-Main>/OSM/Undo",
594 achadwick 65 GDK_z, GDK_CONTROL_MASK, FALSE, FALSE
595 harbaum 64 );
596     } else
597     printf("set environment variable OSM2GO_UNDO_TEST to enable undo framework tests\n");
598 harbaum 1
599 harbaum 64 appdata->menu_item_osm_save_changes = menu_append_new_item(
600 achadwick 55 appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_save_changes), _("_Save local changes"),
601     GTK_STOCK_SAVE, "<OSM2Go-Main>/OSM/SaveChanges",
602     GDK_s, GDK_SHIFT_MASK|GDK_CONTROL_MASK, FALSE, FALSE
603     );
604 harbaum 15
605 achadwick 55 appdata->menu_item_osm_undo_changes = menu_append_new_item(
606     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_undo_changes), _("Disca_rd local changes..."),
607     GTK_STOCK_DELETE, "<OSM2Go-Main>/OSM/DiscardChanges",
608     0, 0, FALSE, FALSE
609     );
610    
611 harbaum 76 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new());
612     appdata->menu_item_osm_relations = menu_append_new_item(
613     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_osm_relations), _("_Relations..."),
614     NULL, "<OSM2Go-Main>/OSM/Relations",
615     GDK_r, GDK_SHIFT_MASK|GDK_CONTROL_MASK, FALSE, FALSE
616     );
617    
618 harbaum 1 /* -------------------- wms submenu -------------------- */
619    
620 achadwick 55 appdata->menu_wms = item = gtk_menu_item_new_with_mnemonic( _("_WMS") );
621 achadwick 37 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
622 harbaum 1 submenu = gtk_menu_new();
623 achadwick 55 gtk_menu_set_accel_group(GTK_MENU(submenu), accel_grp);
624 harbaum 1 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
625    
626 achadwick 55 menu_append_new_item(
627     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_wms_import), _("_Import..."),
628     GTK_STOCK_INDEX, "<OSM2Go-Main>/WMS/Import",
629     0, 0, FALSE, FALSE
630     );
631 harbaum 1
632 achadwick 55 appdata->menu_item_wms_clear = menu_append_new_item(
633     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_wms_clear), _("_Clear"),
634     GTK_STOCK_CLEAR, "<OSM2Go-Main>/WMS/Clear",
635     0, 0, FALSE, FALSE
636     );
637     gtk_widget_set_sensitive(appdata->menu_item_wms_clear, FALSE);
638 harbaum 1
639 achadwick 55 appdata->menu_item_wms_adjust = menu_append_new_item(
640     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_wms_adjust), _("_Adjust"),
641     NULL, "<OSM2Go-Main>/WMS/Adjust",
642     0, 0, FALSE, FALSE
643     );
644     gtk_widget_set_sensitive(appdata->menu_item_wms_adjust, FALSE);
645 harbaum 1
646     /* -------------------- map submenu -------------------- */
647    
648 achadwick 55 appdata->menu_map = item = gtk_menu_item_new_with_mnemonic( _("_Map") );
649 achadwick 37 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
650 harbaum 1 submenu = gtk_menu_new();
651 achadwick 55 gtk_menu_set_accel_group(GTK_MENU(submenu), accel_grp);
652 harbaum 1 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
653    
654 achadwick 55 appdata->menu_item_map_hide_sel = menu_append_new_item(
655     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_map_hide_sel), _("_Hide selected"),
656     GTK_STOCK_REMOVE, "<OSM2Go-Main>/Map/HideSelected",
657     0, 0, FALSE, FALSE
658     );
659     gtk_widget_set_sensitive(appdata->menu_item_map_hide_sel, FALSE);
660 harbaum 1
661 achadwick 55 appdata->menu_item_map_show_all = menu_append_new_item(
662     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_map_show_all), _("_Show all"),
663     GTK_STOCK_ADD, "<OSM2Go-Main>/Map/ShowAll",
664     0, 0, FALSE, FALSE
665     );
666     gtk_widget_set_sensitive(appdata->menu_item_map_show_all, FALSE);
667 harbaum 1
668 achadwick 37 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new());
669 harbaum 1
670 achadwick 55 menu_append_new_item(
671     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_style), _("St_yle..."),
672     GTK_STOCK_SELECT_COLOR, "<OSM2Go-Main>/Map/Style",
673     0, 0, FALSE, FALSE
674     );
675 harbaum 1
676 achadwick 37 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new());
677 harbaum 1
678 harbaum 24 /* switches mainly intended for testing/debugging */
679 achadwick 55 menu_append_new_item(
680     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_redraw), _("_Redraw"),
681     NULL, "<OSM2Go-Main>/Map/Redraw",
682     GDK_r, GDK_CONTROL_MASK, FALSE, FALSE
683     );
684 harbaum 1
685 achadwick 55 appdata->menu_item_map_no_icons = menu_append_new_item(
686     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_map_no_icons), _("No _icons"),
687     NULL, "<OSM2Go-Main>/Map/NoIcons",
688     0, 0, TRUE, appdata->settings->no_icons
689     );
690 harbaum 14
691 achadwick 55 appdata->menu_item_map_no_antialias = menu_append_new_item(
692     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_map_no_antialias),
693     _("No _antialias"),
694     NULL, "<OSM2Go-Main>/Map/NoAntialias",
695     0, 0, TRUE, appdata->settings->no_antialias
696     );
697 harbaum 24
698 harbaum 1 /* -------------------- track submenu -------------------- */
699    
700 achadwick 55 appdata->track.menu_track = item = gtk_menu_item_new_with_mnemonic(_("_Track"));
701 achadwick 37 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
702 harbaum 1 submenu = gtk_menu_new();
703 achadwick 55 gtk_menu_set_accel_group(GTK_MENU(submenu), accel_grp);
704 harbaum 1 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
705    
706 achadwick 55 appdata->track.menu_item_import = menu_append_new_item(
707     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_track_import), _("_Import..."),
708     NULL, "<OSM2Go-Main>/Track/Import",
709     0, 0, FALSE, FALSE
710     );
711 harbaum 1
712 achadwick 55 appdata->track.menu_item_export = menu_append_new_item(
713     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_track_export), _("_Export..."),
714     NULL, "<OSM2Go-Main>/Track/Export",
715     0, 0, FALSE, FALSE
716     );
717 harbaum 1
718 achadwick 55 appdata->track.menu_item_clear = menu_append_new_item(
719     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_track_clear), _("_Clear"),
720     GTK_STOCK_CLEAR, "<OSM2Go-Main>/Track/Clear",
721     0, 0, FALSE, FALSE
722     );
723 harbaum 1
724 achadwick 55
725     appdata->track.menu_item_gps = menu_append_new_item(
726     appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_track_gps), _("_GPS"),
727     NULL, "<OSM2Go-Main>/Track/GPS",
728     GDK_g, GDK_CONTROL_MASK|GDK_SHIFT_MASK, TRUE, FALSE
729     );
730 harbaum 1
731     /* ------------------------------------------------------- */
732    
733 achadwick 37 gtk_menu_shell_append(GTK_MENU_SHELL(about_quit_items_menu),
734     gtk_separator_menu_item_new());
735 harbaum 1
736 achadwick 55 menu_append_new_item(
737     appdata, about_quit_items_menu, GTK_SIGNAL_FUNC(cb_menu_about), _("_About..."),
738     GTK_STOCK_ABOUT, "<OSM2Go-Main>/About",
739     0, 0, FALSE, FALSE
740     );
741 harbaum 1
742 achadwick 55 menu_append_new_item(
743     appdata, about_quit_items_menu, GTK_SIGNAL_FUNC(cb_menu_quit), _("_Quit"),
744     GTK_STOCK_QUIT, "<OSM2Go-Main>/Quit",
745     0, 0, FALSE, FALSE
746     );
747 harbaum 1
748 achadwick 55 gtk_window_add_accel_group(GTK_WINDOW(appdata->window), accel_grp);
749    
750 harbaum 1 #ifdef USE_HILDON
751     hildon_window_set_menu(appdata->window, GTK_MENU(menu));
752     #else
753 achadwick 37 GtkWidget *menu_bar = menu;
754 harbaum 1
755 achadwick 55 #ifndef UISPECIFIC_MAIN_MENU_IS_MENU_BAR
756 achadwick 37 // we need to make one first
757     menu_bar = gtk_menu_bar_new();
758    
759 harbaum 1 GtkWidget *root_menu = gtk_menu_item_new_with_label (_("Menu"));
760     gtk_widget_show(root_menu);
761    
762     gtk_menu_bar_append(menu_bar, root_menu);
763     gtk_menu_item_set_submenu(GTK_MENU_ITEM (root_menu), menu);
764    
765     gtk_widget_show(menu_bar);
766 achadwick 55 #endif //UISPECIFIC_MAIN_MENU_IS_MENU_BAR
767 achadwick 37
768 harbaum 1 gtk_box_pack_start(GTK_BOX(appdata->vbox), menu_bar, 0, 0, 0);
769 achadwick 37
770     #endif //USE_HILDON
771 harbaum 1 }
772    
773     /********************* end of menu **********************/
774    
775 achadwick 55 #ifdef UISPECIFIC_MENU_HAS_ACCELS
776     #define ACCELS_FILE "accels"
777 harbaum 1
778 achadwick 55 static void menu_accels_load(appdata_t *appdata) {
779     char *accels_file = g_strdup_printf("%s/" ACCELS_FILE,
780     appdata->settings->base_path);
781     gtk_accel_map_load(accels_file);
782     g_free(accels_file);
783     }
784    
785     static void menu_accels_save(appdata_t *appdata) {
786     char *accels_file = g_strdup_printf("%s" ACCELS_FILE,
787     appdata->settings->base_path);
788     gtk_accel_map_save(accels_file);
789     g_free(accels_file);
790     }
791    
792     #endif
793    
794    
795 harbaum 1 void cleanup(appdata_t *appdata) {
796 achadwick 55 #ifdef UISPECIFIC_MENU_HAS_ACCELS
797     menu_accels_save(appdata);
798     #endif
799    
800 harbaum 1 settings_save(appdata->settings);
801    
802     #ifdef USE_HILDON
803     if(appdata->osso_context)
804     osso_deinitialize(appdata->osso_context);
805    
806     appdata->program = NULL;
807     #endif
808    
809     printf("waiting for gtk to shut down ");
810    
811     /* let gtk clean up first */
812     while(gtk_events_pending()) {
813     putchar('.');
814     gtk_main_iteration();
815     }
816    
817     printf(" ok\n");
818    
819     /* save project file */
820     if(appdata->project)
821     project_save(GTK_WIDGET(appdata->window), appdata->project);
822    
823     map_remove_bg_image(appdata->map);
824    
825     osm_free(&appdata->icon, appdata->osm);
826    
827     curl_global_cleanup();
828    
829     josm_presets_free(appdata->presets);
830    
831     icon_free_all(&appdata->icon);
832    
833     gps_release(appdata);
834    
835     settings_free(appdata->settings);
836    
837     statusbar_free(appdata->statusbar);
838    
839     iconbar_free(appdata->iconbar);
840    
841     project_free(appdata->project);
842    
843 harbaum 69 if(appdata->menu_item_osm_undo)
844     undo_free(appdata->undo.state);
845 harbaum 54
846 harbaum 1 puts("everything is gone");
847     }
848    
849     void on_window_destroy (GtkWidget *widget, gpointer data) {
850     appdata_t *appdata = (appdata_t*)data;
851    
852     gtk_main_quit();
853     appdata->window = NULL;
854     }
855    
856     gboolean on_window_key_press(GtkWidget *widget,
857     GdkEventKey *event, gpointer data) {
858     appdata_t *appdata = (appdata_t*)data;
859     int handled = FALSE;
860    
861     // the map handles some keys on its own ...
862     switch(event->keyval) {
863    
864 harbaum 22 #ifdef USE_HILDON
865     /* this is in fact a mapping to GDK_F6 */
866 harbaum 1 case HILDON_HARDKEY_FULLSCREEN:
867 harbaum 22 #else
868     case GDK_F11:
869     #endif
870     if(!gtk_check_menu_item_get_active(
871     GTK_CHECK_MENU_ITEM(appdata->menu_item_view_fullscreen))) {
872     gtk_window_fullscreen(GTK_WINDOW(appdata->window));
873 harbaum 1 gtk_check_menu_item_set_active(
874 harbaum 22 GTK_CHECK_MENU_ITEM(appdata->menu_item_view_fullscreen), TRUE);
875     } else {
876 harbaum 1 gtk_window_unfullscreen(GTK_WINDOW(appdata->window));
877 harbaum 22 gtk_check_menu_item_set_active(
878     GTK_CHECK_MENU_ITEM(appdata->menu_item_view_fullscreen), FALSE);
879     }
880    
881     handled = TRUE;
882 harbaum 1 break;
883     }
884    
885     /* forward unprocessed key presses to map */
886     if(!handled && appdata->project && appdata->osm)
887     handled = map_key_press_event(appdata, event);
888    
889     return handled;
890     }
891    
892     int main(int argc, char *argv[]) {
893     appdata_t appdata;
894    
895     /* init appdata */
896     memset(&appdata, 0, sizeof(appdata));
897    
898     printf("Using locale for %s in %s\n", PACKAGE, LOCALEDIR);
899    
900     setlocale(LC_ALL, "");
901     bindtextdomain(PACKAGE, LOCALEDIR);
902     bind_textdomain_codeset(PACKAGE, "UTF-8");
903     textdomain(PACKAGE);
904    
905     /* Must initialize libcurl before any threads are started */
906     curl_global_init(CURL_GLOBAL_ALL);
907    
908     g_thread_init(NULL);
909    
910 harbaum 118 gtk_init (&argc, &argv);
911    
912 harbaum 1 gps_init(&appdata);
913    
914     #ifdef USE_HILDON
915     printf("Installing osso context for \"org.harbaum." PACKAGE "\"\n");
916     appdata.osso_context = osso_initialize("org.harbaum."PACKAGE,
917     VERSION, TRUE, NULL);
918     if(appdata.osso_context == NULL)
919     fprintf(stderr, "error initiating osso context\n");
920    
921     dbus_register(&appdata);
922     #endif
923    
924     #ifdef USE_HILDON
925     /* Create the hildon program and setup the title */
926     appdata.program = HILDON_PROGRAM(hildon_program_get_instance());
927     g_set_application_name("OSM2Go");
928    
929     /* Create HildonWindow and set it to HildonProgram */
930     appdata.window = HILDON_WINDOW(hildon_window_new());
931     hildon_program_add_window(appdata.program, appdata.window);
932     #else
933     /* Create a Window. */
934     appdata.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
935     gtk_window_set_title(GTK_WINDOW(appdata.window), "OSM2Go");
936     /* Set a decent default size for the window. */
937     gtk_window_set_default_size(GTK_WINDOW(appdata.window),
938     DEFAULT_WIDTH, DEFAULT_HEIGHT);
939     gtk_window_set_icon(GTK_WINDOW(appdata.window),
940     icon_load(&appdata.icon, PACKAGE));
941     #endif
942    
943     g_signal_connect(G_OBJECT(appdata.window), "destroy",
944     G_CALLBACK(on_window_destroy), &appdata);
945    
946     g_signal_connect(G_OBJECT(appdata.window), "key_press_event",
947     G_CALLBACK(on_window_key_press), &appdata);
948    
949 harbaum 14 /* user specific init */
950     appdata.settings = settings_load();
951    
952 harbaum 1 appdata.vbox = gtk_vbox_new(FALSE,0);
953     menu_create(&appdata);
954 achadwick 55 #ifdef UISPECIFIC_MENU_HAS_ACCELS
955     menu_accels_load(&appdata);
956     #endif
957 harbaum 1
958     /* ----------------------- setup main window ---------------- */
959    
960     GtkWidget *hbox = gtk_hbox_new(FALSE,0);
961     GtkWidget *vbox = gtk_vbox_new(FALSE,0);
962    
963     #ifdef PORTRAIT
964     gtk_box_pack_start(GTK_BOX(vbox), iconbar_new(&appdata), FALSE, FALSE, 0);
965     #endif
966 harbaum 22
967     /* generate main map view */
968     GtkWidget *map = map_new(&appdata);
969     if(!map) {
970     cleanup(&appdata);
971     return -1;
972     }
973    
974     gtk_box_pack_start(GTK_BOX(vbox), map, TRUE, TRUE, 0);
975 harbaum 1 gtk_box_pack_start(GTK_BOX(vbox), statusbar_new(&appdata), FALSE, FALSE, 0);
976    
977     #ifndef PORTRAIT
978     gtk_box_pack_start(GTK_BOX(hbox), iconbar_new(&appdata), FALSE, FALSE, 0);
979     #endif
980     gtk_box_pack_start(GTK_BOX(hbox), gtk_vseparator_new(), FALSE, FALSE, 0);
981     gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
982    
983     gtk_box_pack_start(GTK_BOX(appdata.vbox), hbox, TRUE, TRUE, 0);
984    
985     gtk_container_add(GTK_CONTAINER(appdata.window), appdata.vbox);
986    
987     gtk_widget_show_all(GTK_WIDGET(appdata.window));
988    
989     appdata.presets = josm_presets_load();
990    
991     /* let gtk do its thing before loading the data, */
992     /* so the user sees something */
993     while(gtk_events_pending()) {
994     putchar('.');
995     gtk_main_iteration();
996     }
997    
998     /* load project if one is specified in the settings */
999     if(appdata.settings->project)
1000     project_load(&appdata, appdata.settings->project);
1001    
1002 harbaum 4 main_ui_enable(&appdata);
1003 harbaum 1
1004     /* ------------ jump into main loop ---------------- */
1005    
1006     gtk_main();
1007    
1008 harbaum 4 puts("gtk_main() left");
1009    
1010 harbaum 1 track_save(appdata.project, appdata.track.track);
1011 harbaum 118 track_clear(&appdata, appdata.track.track);
1012 harbaum 1
1013     /* save a diff if there are dirty entries */
1014     diff_save(appdata.project, appdata.osm);
1015    
1016     cleanup(&appdata);
1017    
1018     return 0;
1019     }
1020 achadwick 55
1021     // vim:et:ts=8:sw=2:sts=2:ai