Diff of /trunk/src/main.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 24 by harbaum, Sun Dec 21 11:49:35 2008 UTC revision 245 by harbaum, Sun Jul 26 18:54:07 2009 UTC
# Line 1  Line 1 
1  /*  /*
2     * Copyright (C) 2008 Till Harbaum <till@harbaum.org>.
3     *
4   * This file is part of OSM2Go.   * This file is part of OSM2Go.
5   *   *
6   * OSM2Go is free software: you can redistribute it and/or modify   * OSM2Go is free software: you can redistribute it and/or modify
# Line 21  Line 23 
23  #include <curl/curl.h>  #include <curl/curl.h>
24  #include <gdk/gdkkeysyms.h>  #include <gdk/gdkkeysyms.h>
25    
26    #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    #include <gdk/gdkx.h>
31    #include <X11/Xatom.h>
32    #endif
33    
34  #include "appdata.h"  #include "appdata.h"
35    #include "banner.h"
36    
37  /* disable/enable main screen control dependant on presence of open project */  /* disable/enable main screen control dependant on presence of open project */
38  static void main_ui_enable(appdata_t *appdata) {  void main_ui_enable(appdata_t *appdata) {
39    gboolean project_valid = (appdata->project != NULL);    gboolean project_valid = (appdata->project != NULL);
40    gboolean osm_valid = (appdata->osm != NULL);    gboolean osm_valid = (appdata->osm != NULL);
41    
# Line 33  static void main_ui_enable(appdata_t *ap Line 44  static void main_ui_enable(appdata_t *ap
44      map_action_cancel(appdata);      map_action_cancel(appdata);
45    
46    /* ---- set project name as window title ----- */    /* ---- set project name as window title ----- */
47  #ifndef USE_HILDON  #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    char *str = NULL;    char *str = NULL;
54    #ifdef USE_HILDON
55    if(project_valid)    if(project_valid)
56      str = g_strdup_printf("OSM2Go - %s", appdata->project->name);      str = g_markup_printf_escaped("<b>%s</b> - OSM2Go",
57                                      appdata->project->name);
58      else
59        str = g_markup_printf_escaped("OSM2Go");
60    
61      hildon_window_set_markup(HILDON_WINDOW(appdata->window), str);
62    #else
63      if(project_valid)
64        str = g_strdup_printf("%s - OSM2Go", appdata->project->name);
65    else    else
66      str = g_strdup_printf("OSM2Go");      str = g_strdup_printf("OSM2Go");
67    
68    gtk_window_set_title(GTK_WINDOW(appdata->window), str);    gtk_window_set_title(GTK_WINDOW(appdata->window), str);
69    #endif
70    g_free(str);    g_free(str);
 #else  
   if(project_valid)  
     gtk_window_set_title(GTK_WINDOW(appdata->window), appdata->project->name);  
   else  
     gtk_window_set_title(GTK_WINDOW(appdata->window), "");  
71  #endif  #endif
72    
73    if(appdata->iconbar && appdata->iconbar->toolbar)    if(appdata->iconbar && appdata->iconbar->toolbar)
74      gtk_widget_set_sensitive(appdata->iconbar->toolbar, osm_valid);      gtk_widget_set_sensitive(appdata->iconbar->toolbar, osm_valid);
   
75    /* disable all menu entries related to map */    /* disable all menu entries related to map */
76    gtk_widget_set_sensitive(appdata->menu_osm, project_valid);    gtk_widget_set_sensitive(appdata->submenu_map, project_valid);
77    gtk_widget_set_sensitive(appdata->menu_item_osm_upload, osm_valid);    gtk_widget_set_sensitive(appdata->menu_item_map_upload, osm_valid);
78    gtk_widget_set_sensitive(appdata->menu_item_osm_diff, osm_valid);    if(appdata->menu_item_map_undo)
79    gtk_widget_set_sensitive(appdata->menu_item_osm_undo_changes, osm_valid);      gtk_widget_set_sensitive(appdata->menu_item_map_undo, osm_valid);
80    gtk_widget_set_sensitive(appdata->track.menu_track, osm_valid);    if(appdata->menu_item_map_save_changes)
81    gtk_widget_set_sensitive(appdata->menu_view, osm_valid);      gtk_widget_set_sensitive(appdata->menu_item_map_save_changes, osm_valid);
82    gtk_widget_set_sensitive(appdata->menu_wms, osm_valid);    gtk_widget_set_sensitive(appdata->menu_item_map_undo_changes, osm_valid);
83    gtk_widget_set_sensitive(appdata->menu_map, osm_valid);    gtk_widget_set_sensitive(appdata->menu_item_map_relations, osm_valid);
84    gtk_widget_set_sensitive(appdata->menu_item_project_close, project_valid);    gtk_widget_set_sensitive(appdata->track.submenu_track, osm_valid);
85      gtk_widget_set_sensitive(appdata->submenu_view, osm_valid);
86      gtk_widget_set_sensitive(appdata->submenu_wms, osm_valid);
87    
88    #ifdef ZOOM_BUTTONS
89      gtk_widget_set_sensitive(appdata->btn_zoom_in, osm_valid);
90      gtk_widget_set_sensitive(appdata->btn_zoom_out, osm_valid);
91    #endif
92    
93    if(!project_valid)    if(!project_valid)
94      statusbar_set(appdata, _("Please load or create a project"), FALSE);      statusbar_set(appdata, _("Please load or create a project"), FALSE);
# Line 69  static void main_ui_enable(appdata_t *ap Line 96  static void main_ui_enable(appdata_t *ap
96    
97  /******************** begin of menu *********************/  /******************** begin of menu *********************/
98    
 #if 0 // simplify menu  
 static struct {  
   enum { MENU_END, MENU_ITEM, MENU_SUB, MENU_SUB_END, MENU_SEP }  type;  
   
   char *title;  
   GCallback c_handler;  
 } menu[] = {  
   { MENU_SUB, "_OSM", NULL },  
   
   { MENU_END,  NULL, NULL },  
 };  
 #endif  
   
99  static void  static void
100  cb_menu_project_open(GtkWidget *window, gpointer data) {  cb_menu_project_open(GtkMenuItem *item, gpointer data) {
101    appdata_t *appdata = (appdata_t*)data;    appdata_t *appdata = (appdata_t*)data;
102    project_load(appdata, NULL);    project_load(appdata, NULL);
103    main_ui_enable(appdata);    main_ui_enable(appdata);
104  }  }
105    
106  static void  static void
107  cb_menu_project_close(GtkWidget *window, gpointer data) {  cb_menu_project_wizard(GtkMenuItem *item, gpointer data) {
108    appdata_t *appdata = (appdata_t*)data;    appdata_t *appdata = (appdata_t*)data;
109    project_close(appdata);    project_wizard(appdata);
   main_ui_enable(appdata);  
110  }  }
111    
112  static void  static void
113  cb_menu_about(GtkWidget *window, gpointer data) {  cb_menu_about(GtkMenuItem *item, gpointer data) {
114    GtkAboutDialog *about = GTK_ABOUT_DIALOG(gtk_about_dialog_new());    appdata_t *appdata = (appdata_t*)data;
   
   gtk_about_dialog_set_name(about, "OSM2Go");  
   gtk_about_dialog_set_version(about, VERSION);  
   gtk_about_dialog_set_copyright(about, _("Copyright 2008"));  
115    
116    const gchar *authors[] = {    const gchar *authors[] = {
117      "Till Harbaum <till@harbaum.org>",      "Till Harbaum <till@harbaum.org>",
118      "Andrew Chadwick",      "Andrew Chadwick <andrewc-osm2go@piffle.org>",
119        "Marcus Bauer <marcus.bauer@gmail.com>",
120        "John Stowers <john.stowers@gmail.com>",
121      NULL };      NULL };
122    
123    gtk_about_dialog_set_authors(about, authors);    const gchar *artists[] = {
124        "Andrew Zhilin <drew.zhilin@gmail.com>",
125    gtk_about_dialog_set_website(about,      NULL };
        _("http://www.harbaum.org/till/maemo"));  
   
   gtk_about_dialog_set_comments(about,  
        _("Mobile OSM Editor"));  
126    
127    gtk_widget_show_all(GTK_WIDGET(about));    gtk_show_about_dialog(GTK_WINDOW(appdata->window),
128    gtk_dialog_run(GTK_DIALOG(about));                          "name", "OSM2Go",
129    gtk_widget_destroy(GTK_WIDGET(about));                          "version", VERSION,
130                            "copyright", _("Copyright 2008-2009"),
131                            "authors", authors,
132                            "artists", artists,
133                            "website", _("http://www.harbaum.org/till/maemo"),
134                            "comments", _("Mobile OSM Editor"),
135                            NULL);
136  }  }
137    
138  void on_window_destroy (GtkWidget *widget, gpointer data);  void on_window_destroy (GtkWidget *widget, gpointer data);
139    
140    #ifndef USE_HILDON
141  static void  static void
142  cb_menu_quit(GtkWidget *window, gpointer data) {  cb_menu_quit(GtkMenuItem *item, gpointer data) {
143    appdata_t *appdata = (appdata_t*)data;    appdata_t *appdata = (appdata_t*)data;
144    gtk_widget_destroy(GTK_WIDGET(appdata->window));    gtk_widget_destroy(GTK_WIDGET(appdata->window));
145  }  }
146    #endif
147    
148  static void  static void
149  cb_menu_upload(GtkWidget *window, gpointer data) {  cb_menu_upload(GtkMenuItem *item, gpointer data) {
150    appdata_t *appdata = (appdata_t*)data;    appdata_t *appdata = (appdata_t*)data;
151    if(!appdata->osm || !appdata->project) return;    if(!appdata->osm || !appdata->project) return;
152    
153      if(project_check_demo(GTK_WIDGET(appdata->window), appdata->project))
154        return;
155    
156    osm_upload(appdata, appdata->osm, appdata->project);    osm_upload(appdata, appdata->osm, appdata->project);
157  }  }
158    
159  static void  static void
160  cb_menu_download(GtkWidget *window, gpointer data) {  cb_menu_download(GtkMenuItem *item, gpointer data) {
161    appdata_t *appdata = (appdata_t*)data;    appdata_t *appdata = (appdata_t*)data;
162    if(!appdata->project) return;    if(!appdata->project) return;
163    
164      if(project_check_demo(GTK_WIDGET(appdata->window), appdata->project))
165        return;
166    
167    /* if we have valid osm data loaded: save state first */    /* if we have valid osm data loaded: save state first */
168    if(appdata->osm) {    if(appdata->osm) {
169      /* redraw the entire map by destroying all map items and redrawing them */      /* redraw the entire map by destroying all map items and redrawing them */
# Line 154  cb_menu_download(GtkWidget *window, gpoi Line 175  cb_menu_download(GtkWidget *window, gpoi
175    }    }
176    
177    // download    // download
178    if(osm_download(GTK_WIDGET(appdata->window), appdata->project)) {    if(osm_download(GTK_WIDGET(appdata->window), appdata->settings,
179      appdata->osm = osm_parse(appdata->project->osm);                    appdata->project)) {
180        banner_busy_start(appdata, 1, "Redrawing");
181        appdata->osm = osm_parse(appdata->project->path, appdata->project->osm);
182      diff_restore(appdata, appdata->project, appdata->osm);      diff_restore(appdata, appdata->project, appdata->osm);
183      map_paint(appdata);      map_paint(appdata);
184        banner_busy_stop(appdata); //"Redrawing"
185    }    }
186    
187    main_ui_enable(appdata);    main_ui_enable(appdata);
188  }  }
189    
190  static void  static void
191  cb_menu_wms_import(GtkWidget *window, gpointer data) {  cb_menu_wms_import(GtkMenuItem *item, gpointer data) {
192    appdata_t *appdata = (appdata_t*)data;    appdata_t *appdata = (appdata_t*)data;
193    wms_import(appdata);    wms_import(appdata);
194  }  }
195    
196  static void  static void
197  cb_menu_wms_clear(GtkWidget *window, gpointer data) {  cb_menu_wms_clear(GtkMenuItem *item, gpointer data) {
198    appdata_t *appdata = (appdata_t*)data;    appdata_t *appdata = (appdata_t*)data;
199    wms_remove(appdata);    wms_remove(appdata);
200  }  }
201    
202  static void  static void
203  cb_menu_wms_adjust(GtkWidget *window, gpointer data) {  cb_menu_wms_adjust(GtkMenuItem *item, gpointer data) {
204    appdata_t *appdata = (appdata_t*)data;    appdata_t *appdata = (appdata_t*)data;
205    map_action_set(appdata, MAP_ACTION_BG_ADJUST);    map_action_set(appdata, MAP_ACTION_BG_ADJUST);
206  }  }
# Line 184  cb_menu_wms_adjust(GtkWidget *window, gp Line 208  cb_menu_wms_adjust(GtkWidget *window, gp
208  /* ----------- hide objects for performance reasons ----------- */  /* ----------- hide objects for performance reasons ----------- */
209    
210  static void  static void
211  cb_menu_map_hide_sel(GtkWidget *window, gpointer data) {  cb_menu_map_hide_sel(GtkMenuItem *item, gpointer data) {
212    appdata_t *appdata = (appdata_t*)data;    appdata_t *appdata = (appdata_t*)data;
213    map_hide_selected(appdata);    map_hide_selected(appdata);
214  }  }
215    
216  static void  static void
217  cb_menu_map_show_all(GtkWidget *window, gpointer data) {  cb_menu_map_show_all(GtkMenuItem *item, gpointer data) {
218    appdata_t *appdata = (appdata_t*)data;    appdata_t *appdata = (appdata_t*)data;
219    map_show_all(appdata);    map_show_all(appdata);
220  }  }
221    
222  /* ---------------------------------------------------------- */  /* ---------------------------------------------------------- */
223    
224  #if 1  // mainly for testing  #if defined(USE_HILDON) && (MAEMO_VERSION_MAJOR == 5)
225  static void  #define MENU_CHECK_ITEM HildonCheckButton
226  cb_menu_redraw(GtkWidget *window, gpointer data) {  #define MENU_CHECK_ITEM_ACTIVE(a) hildon_check_button_get_active(a)
227    appdata_t *appdata = (appdata_t*)data;  #else
228    #define MENU_CHECK_ITEM GtkCheckMenuItem
229    #define MENU_CHECK_ITEM_ACTIVE(a) gtk_check_menu_item_get_active(a)
230    #endif
231    
232    /* redraw the entire map by destroying all map items and redrawing them */  static void
233    track_save(appdata->project, appdata->track.track);  cb_menu_map_no_icons(MENU_CHECK_ITEM *item, appdata_t *appdata) {
   diff_save(appdata->project, appdata->osm);  
   map_clear(appdata, MAP_LAYER_ALL);  
   osm_free(&appdata->icon, appdata->osm);  
234    
235    appdata->osm = osm_parse(appdata->project->osm);    banner_busy_start(appdata, 1, "Redrawing");
236    diff_restore(appdata, appdata->project, appdata->osm);    map_clear(appdata, MAP_LAYER_OBJECTS_ONLY);
   map_paint(appdata);  
237    
238    appdata->track.track = track_restore(appdata, appdata->project);    appdata->settings->no_icons = MENU_CHECK_ITEM_ACTIVE(item);
   if(appdata->track.track)  
     map_track_draw(appdata->map, appdata->track.track);  
239    
240    wms_load(appdata);    map_paint(appdata);
241      banner_busy_stop(appdata); //"Redrawing"
242  }  }
 #endif  
243    
244  static void  static void
245  cb_menu_style(GtkWidget *widget, gpointer data) {  cb_menu_style(GtkMenuItem *item, gpointer data) {
246    appdata_t *appdata = (appdata_t*)data;    appdata_t *appdata = (appdata_t*)data;
247    
248    style_select(GTK_WIDGET(appdata->window), appdata);    style_select(GTK_WIDGET(appdata->window), appdata);
249  }  }
250    
251  static void  static void
252  cb_menu_map_no_icons(GtkWidget *widget, gpointer data) {  cb_menu_undo(GtkMenuItem *item, gpointer data) {
253    appdata_t *appdata = (appdata_t*)data;    appdata_t *appdata = (appdata_t*)data;
254    
255    map_clear(appdata, MAP_LAYER_OBJECTS_ONLY);    undo(appdata);
   appdata->settings->no_icons =  
     gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));  
   map_paint(appdata);  
 }  
   
 static void  
 cb_menu_map_no_antialias(GtkWidget *widget, gpointer data) {  
   appdata_t *appdata = (appdata_t*)data;  
256    
257    map_clear(appdata, MAP_LAYER_OBJECTS_ONLY);    // the banner will be displayed from within undo with more details
   appdata->settings->no_antialias =  
     gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));  
   map_paint(appdata);  
258  }  }
259    
260  static void  static void
261  cb_menu_save_changes(GtkWidget *widget, gpointer data) {  cb_menu_save_changes(GtkMenuItem *item, gpointer data) {
262    appdata_t *appdata = (appdata_t*)data;    appdata_t *appdata = (appdata_t*)data;
263    
264    diff_save(appdata->project, appdata->osm);    diff_save(appdata->project, appdata->osm);
265    statusbar_set(appdata, _("Saved all changes made "    banner_show_info(appdata, _("Saved local changes"));
                            "to this project so far"), FALSE);  
266  }  }
267    
268  static void  static void
269  cb_menu_undo_changes(GtkWidget *widget, gpointer data) {  cb_menu_undo_changes(GtkMenuItem *item, gpointer data) {
270    appdata_t *appdata = (appdata_t*)data;    appdata_t *appdata = (appdata_t*)data;
271    
272    if(!yes_no_f(GTK_WIDGET(appdata->window), NULL, 0, 0,    if(!yes_no_f(GTK_WIDGET(appdata->window), NULL, 0, 0,
273                 _("Undo all changes?"),                 _("Undo all changes?"),
274                 _("Do you really want to undo all your changes "                 _("Throw away all the changes you've not "
275                   "not uploaded so far? This cannot be undone!")))                   "uploaded yet? This can't be undone.")))
276      return;      return;
277    
278      banner_busy_start(appdata, 1, _("Redrawing"));
279    map_clear(appdata, MAP_LAYER_OBJECTS_ONLY);    map_clear(appdata, MAP_LAYER_OBJECTS_ONLY);
280    osm_free(&appdata->icon, appdata->osm);    osm_free(&appdata->icon, appdata->osm);
281    diff_remove(appdata->project);    diff_remove(appdata->project);
282    appdata->osm = osm_parse(appdata->project->osm);    appdata->osm = osm_parse(appdata->project->path, appdata->project->osm);
283    map_paint(appdata);    map_paint(appdata);
284      banner_busy_stop(appdata);  //"Redrawing"
285    
286    statusbar_set(appdata, _("All changes made "    banner_show_info(appdata, _("Undo all changes"));
                            "so far have been reset"), FALSE);  
287  }  }
288    
289  static void  static void
290  cb_menu_fullscreen(GtkWidget *widget, gpointer data) {  cb_menu_osm_relations(GtkMenuItem *item, appdata_t *appdata) {
291      /* list relations of all objects */
292      relation_list(GTK_WIDGET(appdata->window), appdata, NULL);
293    }
294    
295    #if !defined(USE_HILDON) || (MAEMO_VERSION_MAJOR < 5)
296    static void
297    cb_menu_fullscreen(MENU_CHECK_ITEM *item, gpointer data) {
298    appdata_t *appdata = (appdata_t *)data;    appdata_t *appdata = (appdata_t *)data;
299    
300    if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)))    if(MENU_CHECK_ITEM_ACTIVE(item))
301      gtk_window_fullscreen(GTK_WINDOW(appdata->window));      gtk_window_fullscreen(GTK_WINDOW(appdata->window));
302    else    else
303      gtk_window_unfullscreen(GTK_WINDOW(appdata->window));      gtk_window_unfullscreen(GTK_WINDOW(appdata->window));
304  }  }
305    #endif
306    
307  static void  static void
308  cb_menu_zoomin(GtkWidget *widget, appdata_t *appdata) {  cb_menu_zoomin(GtkMenuItem *item, appdata_t *appdata) {
309    if(!appdata || !appdata->map) return;    if(!appdata || !appdata->map) return;
310    
311    map_set_zoom(appdata->map, appdata->map->state->zoom*ZOOM_FACTOR_MENU, TRUE);    map_set_zoom(appdata->map, appdata->map->state->zoom*ZOOM_FACTOR_MENU, TRUE);
# Line 295  cb_menu_zoomin(GtkWidget *widget, appdat Line 313  cb_menu_zoomin(GtkWidget *widget, appdat
313  }  }
314    
315  static void  static void
316  cb_menu_zoomout(GtkWidget *widget, appdata_t *appdata) {  cb_menu_zoomout(GtkMenuItem *item, appdata_t *appdata) {
317    if(!appdata || !appdata->map) return;    if(!appdata || !appdata->map) return;
318    
319    map_set_zoom(appdata->map, appdata->map->state->zoom/ZOOM_FACTOR_MENU, TRUE);    map_set_zoom(appdata->map, appdata->map->state->zoom/ZOOM_FACTOR_MENU, TRUE);
# Line 303  cb_menu_zoomout(GtkWidget *widget, appda Line 321  cb_menu_zoomout(GtkWidget *widget, appda
321  }  }
322    
323  static void  static void
324  cb_menu_track_import(GtkWidget *window, appdata_t *appdata) {  cb_menu_view_detail_inc(GtkMenuItem *item, gpointer data) {
325      appdata_t *appdata = (appdata_t*)data;
326    
327      printf("detail level increase\n");
328      map_detail_increase(appdata->map);
329    }
330    
331    static void
332    cb_menu_view_detail_normal(GtkMenuItem *item, gpointer data) {
333      appdata_t *appdata = (appdata_t*)data;
334    
335      printf("detail level normal\n");
336      map_detail_normal(appdata->map);
337    }
338    
339    static void
340    cb_menu_view_detail_dec(GtkMenuItem *item, gpointer data) {
341      appdata_t *appdata = (appdata_t*)data;
342    
343      printf("detail level decrease\n");
344      map_detail_decrease(appdata->map);
345    }
346    
347    static void
348    cb_menu_track_import(GtkMenuItem *item, appdata_t *appdata) {
349      g_assert(appdata->settings);
350    
351    /* open a file selector */    /* open a file selector */
352    GtkWidget *dialog;    GtkWidget *dialog;
# Line 320  cb_menu_track_import(GtkWidget *window, Line 363  cb_menu_track_import(GtkWidget *window,
363                          NULL);                          NULL);
364  #endif  #endif
365    
366    /* use path if one is present */    if(appdata->settings->track_path) {
367    if(appdata->track.import_path)      if(!g_file_test(appdata->settings->track_path, G_FILE_TEST_EXISTS)) {
368      gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),        char *last_sep = strrchr(appdata->settings->track_path, '/');
369                                          appdata->track.import_path);        if(last_sep) {
370            *last_sep = 0;  // seperate path from file
371    
372            /* the user just created a new document */
373            gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),
374                                        appdata->settings->track_path);
375            gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog),
376                                              last_sep+1);
377    
378            /* restore full filename */
379            *last_sep = '/';
380          }
381        } else
382          gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog),
383                                        appdata->settings->track_path);
384      }
385    
386    gtk_widget_show_all (GTK_WIDGET(dialog));    gtk_widget_show_all (GTK_WIDGET(dialog));
387    if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_FM_OK) {    if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_FM_OK) {
388      char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));      char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
389    
390      /* load a track */      /* load a track */
391      track_do(appdata, TRACK_IMPORT, filename);      appdata->track.track = track_import(appdata, filename);
392      if(appdata->track.track) {      if(appdata->track.track) {
393          if(appdata->settings->track_path) g_free(appdata->settings->track_path);
394        /* save path if gpx was successfully loaded */        appdata->settings->track_path = g_strdup(filename);
       char *r = strrchr(filename, '/');  
   
       /* there is a delimiter, use everything left of it as path */  
       if(r) {  
         *r = 0;  
         if(appdata->track.import_path) g_free(appdata->track.import_path);  
         appdata->track.import_path = g_strdup(filename);  
         /* restore path ... just in case ... */  
         *r = '/';  
       }  
395      }      }
396      g_free (filename);      g_free (filename);
397    }    }
# Line 352  cb_menu_track_import(GtkWidget *window, Line 400  cb_menu_track_import(GtkWidget *window,
400  }  }
401    
402  static void  static void
403  cb_menu_track_gps(GtkWidget *window, gpointer data) {  cb_menu_track_enable_gps(MENU_CHECK_ITEM *item, appdata_t *appdata) {
404    appdata_t *appdata = (appdata_t*)data;    track_enable_gps(appdata, MENU_CHECK_ITEM_ACTIVE(item));
405    }
406    
407    if(gtk_check_menu_item_get_active(  
408      GTK_CHECK_MENU_ITEM(appdata->track.menu_item_gps))) {  static void
409      track_do(appdata, TRACK_GPS, NULL);  cb_menu_track_follow_gps(MENU_CHECK_ITEM *item, appdata_t *appdata) {
410    } else {    appdata->settings->follow_gps = MENU_CHECK_ITEM_ACTIVE(item);
     track_do(appdata, TRACK_NONE, NULL);  
   }  
411  }  }
412    
413    
414  static void  static void
415  cb_menu_track_export(GtkWidget *window, gpointer data) {  cb_menu_track_export(GtkMenuItem *item, appdata_t *appdata) {
416    appdata_t *appdata = (appdata_t*)data;    g_assert(appdata->settings);
417    messagef(GTK_WIDGET(appdata->window), _("NIY"),  
418             _("Track export is not yet supported."));    /* open a file selector */
419      GtkWidget *dialog;
420    
421    #ifdef USE_HILDON
422      dialog = hildon_file_chooser_dialog_new(GTK_WINDOW(appdata->window),
423                                              GTK_FILE_CHOOSER_ACTION_SAVE);
424    #else
425      dialog = gtk_file_chooser_dialog_new(_("Export track file"),
426                                           GTK_WINDOW(appdata->window),
427                                           GTK_FILE_CHOOSER_ACTION_SAVE,
428                                           GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
429                                           GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
430                                           NULL);
431    #endif
432    
433      printf("set filename <%s>\n", appdata->settings->track_path);
434    
435      if(appdata->settings->track_path) {
436        if(!g_file_test(appdata->settings->track_path, G_FILE_TEST_EXISTS)) {
437          char *last_sep = strrchr(appdata->settings->track_path, '/');
438          if(last_sep) {
439            *last_sep = 0;  // seperate path from file
440    
441            /* the user just created a new document */
442            gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),
443                                                appdata->settings->track_path);
444            gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog),
445                                              last_sep+1);
446    
447            /* restore full filename */
448            *last_sep = '/';
449          }
450        } else
451          gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog),
452                                        appdata->settings->track_path);
453      }
454    
455      if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_FM_OK) {
456        gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
457        if(filename) {
458          printf("export to %s\n", filename);
459    
460          if(!g_file_test(filename, G_FILE_TEST_EXISTS) ||
461             yes_no_f(dialog, appdata, MISC_AGAIN_ID_EXPORT_OVERWRITE,
462                      MISC_AGAIN_FLAG_DONT_SAVE_NO,
463                      "Overwrite existing file",
464                      "The file already exists. "
465                      "Do you really want to replace it?")) {
466            if(appdata->settings->track_path)
467              g_free(appdata->settings->track_path);
468            appdata->settings->track_path = g_strdup(filename);
469    
470            track_export(appdata, filename);
471          }
472        }
473      }
474    
475      gtk_widget_destroy (dialog);
476  }  }
477    
478    
479  static void  static void
480  cb_menu_track_clear(GtkWidget *window, gpointer data) {  cb_menu_track_clear(GtkMenuItem *item, gpointer data) {
481    appdata_t *appdata = (appdata_t*)data;    appdata_t *appdata = (appdata_t*)data;
482    track_do(appdata, TRACK_NONE, NULL);    track_clear(appdata, appdata->track.track);
483      appdata->track.track = NULL;
484  }  }
485    
 void menu_create(appdata_t *appdata) {  
   GtkWidget *menu, *item, *submenu;  
   menu = gtk_menu_new();  
486    
487    
   /* -------------------- Project submenu -------------------- */  
488    
489    item = gtk_menu_item_new_with_label( _("Project") );  /*
490    gtk_menu_append(GTK_MENU_SHELL(menu), item);   *  Platform-specific UI tweaks.
491    submenu = gtk_menu_new();   */
   gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);  
492    
   item = gtk_menu_item_new_with_label( _("Open...") );  
   gtk_menu_append(GTK_MENU_SHELL(submenu), item);  
   g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_project_open),  
                    appdata);  
493    
494    appdata->menu_item_project_close = item =  #ifndef USE_HILDON
495      gtk_menu_item_new_with_label( _("Close") );  #ifdef PORTRAIT
   gtk_menu_append(GTK_MENU_SHELL(submenu), item);  
   g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_project_close),  
                    appdata);  
496    
497    /* --------------- view menu ------------------- */  // Portrait mode, for openmoko-like systems
498    #define uispecific_main_menu_new gtk_menu_new
499    
500    gtk_menu_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());  #else
501    
502    appdata->menu_view = item =  // Regular desktop builds
503      gtk_menu_item_new_with_label( _("View") );  #define uispecific_main_menu_new gtk_menu_bar_new
504    gtk_menu_append(GTK_MENU_SHELL(menu), item);  #define UISPECIFIC_MAIN_MENU_IS_MENU_BAR
505    submenu = gtk_menu_new();  #define UISPECIFIC_MENU_HAS_ICONS
506    gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);  #define UISPECIFIC_MENU_HAS_ACCELS
507    
508    appdata->menu_item_view_fullscreen =  #endif //PORTRAIT
509      item = gtk_check_menu_item_new_with_label( _("Fullscreen") );  #else//USE_HILDON
510    gtk_menu_append(GTK_MENU_SHELL(submenu), item);  
511    g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_fullscreen),  // Maemo/Hildon builds
512    #define uispecific_main_menu_new gtk_menu_new
513    
514    #endif
515    
516    
517    #if !defined(USE_HILDON) || (MAEMO_VERSION_MAJOR < 5)
518    // Half-arsed slapdash common menu item constructor. Let's use GtkBuilder
519    // instead so we have some flexibility.
520    
521    static GtkWidget *
522    menu_append_new_item(appdata_t *appdata,
523                         GtkWidget *menu_shell,
524                         GtkSignalFunc activate_cb,
525                         char *label,
526                         const gchar *icon_name, // stock id or name for icon_load
527                                        // overridden by label, accels, icon_name
528                         const gchar *accel_path,
529                         guint accel_key,      // from gdk/gdkkeysyms.h
530                         GdkModifierType accel_mods, // e.g. GDK_CONTROL_MASK
531                         gboolean enabled,
532                         gboolean is_check, gboolean check_status)
533    {
534      GtkWidget *item = NULL;
535      GtkWidget *image = NULL;
536    
537      gboolean stock_item_known = FALSE;
538      GtkStockItem stock_item;
539      if (icon_name != NULL) {
540        stock_item_known = gtk_stock_lookup(icon_name, &stock_item);
541      }
542    
543      // Icons
544    #ifndef UISPECIFIC_MENU_HAS_ICONS
545      item = is_check ? gtk_check_menu_item_new_with_mnemonic (label)
546                      : gtk_menu_item_new_with_mnemonic       (label);
547    #else
548      if (is_check) {
549        item = gtk_check_menu_item_new_with_mnemonic (label);
550      }
551      else if (!stock_item_known) {
552        GdkPixbuf *pbuf = icon_load(&appdata->icon, icon_name);
553        if (pbuf) {
554          image = gtk_image_new_from_pixbuf(pbuf);
555        }
556        if (image) {
557          item = gtk_image_menu_item_new_with_mnemonic(label);
558          gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
559        }
560        else {
561          item = gtk_menu_item_new_with_mnemonic(label);
562        }
563      }
564      else {
565        item = gtk_image_menu_item_new_with_mnemonic(label);
566        image = gtk_image_new_from_stock(icon_name, GTK_ICON_SIZE_MENU);
567        gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
568      }
569    #endif
570    
571    #ifdef UISPECIFIC_MENU_HAS_ACCELS
572      // Accelerators
573      // Default
574      if (accel_path != NULL) {
575        gtk_menu_item_set_accel_path(GTK_MENU_ITEM(item), accel_path);
576        if (accel_key != 0) {
577          gtk_accel_map_add_entry( accel_path, accel_key, accel_mods );
578        }
579        else if (stock_item_known) {
580          gtk_accel_map_add_entry( accel_path, stock_item.keyval,
581                                   stock_item.modifier );
582        }
583      }
584    #endif
585    
586      gtk_menu_shell_append(GTK_MENU_SHELL(menu_shell), GTK_WIDGET(item));
587      gtk_widget_set_sensitive(GTK_WIDGET(item), enabled);
588      if (is_check)
589        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), check_status);
590    
591      g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(activate_cb),
592                     appdata);                     appdata);
593      return item;
594    }
595    
596    item = gtk_menu_item_new_with_label( _("Zoom +" ));  void menu_create(appdata_t *appdata) {
597    gtk_menu_append(GTK_MENU_SHELL(submenu), item);    GtkWidget *menu, *item, *submenu;
598    g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_zoomin), appdata);    GtkWidget *about_quit_items_menu;
599    
600    item = gtk_menu_item_new_with_label( _("Zoom -") );    if (g_module_supported()) {
601    gtk_menu_append(GTK_MENU_SHELL(submenu), item);      printf("*** can use GModule: consider using GtkUIManager / GtkBuilder\n");
602    g_signal_connect(item, "activate",    }
603                     GTK_SIGNAL_FUNC(cb_menu_zoomout), appdata);  
604      menu = uispecific_main_menu_new();
605      about_quit_items_menu = menu;
606    
607    /* -------------------- OSM submenu -------------------- */    /* -------------------- Project submenu -------------------- */
608    
609      GtkAccelGroup *accel_grp = gtk_accel_group_new();
610    
611    appdata->menu_osm = item = gtk_menu_item_new_with_label( _("OSM") );  #ifndef USE_HILDON
612    gtk_menu_append(GTK_MENU_SHELL(menu), item);    item = gtk_menu_item_new_with_mnemonic( _("_Project") );
613      gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
614    submenu = gtk_menu_new();    submenu = gtk_menu_new();
615      gtk_menu_set_accel_group(GTK_MENU(submenu), accel_grp);
616    gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);    gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
617    #ifdef UISPECIFIC_MAIN_MENU_IS_MENU_BAR
618      about_quit_items_menu = submenu;
619    #endif
620    
621    appdata->menu_item_osm_upload = item =    menu_append_new_item(
622      gtk_menu_item_new_with_label( _("Upload...") );      appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_project_open), _("_Open"),
623    gtk_menu_append(GTK_MENU_SHELL(submenu), item);      GTK_STOCK_OPEN, "<OSM2Go-Main>/Project/Open",
624    g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_upload), appdata);      0, 0, TRUE, FALSE, FALSE
625      );
626    item = gtk_menu_item_new_with_label( _("Download...") );  
627    gtk_menu_append(GTK_MENU_SHELL(submenu), item);    menu_append_new_item(
628    g_signal_connect(item, "activate",      appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_project_wizard), _("_Wizard"),
629                     GTK_SIGNAL_FUNC(cb_menu_download), appdata);      GTK_STOCK_NEW, "<OSM2Go-Main>/Project/Wizard",
630        0, 0, TRUE, FALSE, FALSE
631    gtk_menu_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new());    );
632    #else
633    appdata->menu_item_osm_diff = item =    menu_append_new_item(
634      gtk_menu_item_new_with_label( _("Save diff file") );      appdata, menu, GTK_SIGNAL_FUNC(cb_menu_project_open), _("_Project"),
635    gtk_menu_append(GTK_MENU_SHELL(submenu), item);      GTK_STOCK_OPEN, "<OSM2Go-Main>/Project",
636    g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_save_changes),      0, 0, TRUE, FALSE, FALSE
637                     appdata);    );
638    #endif
639    
640    appdata->menu_item_osm_undo_changes = item =    /* --------------- view menu ------------------- */
     gtk_menu_item_new_with_label( _("Undo all changes...") );  
   gtk_menu_append(GTK_MENU_SHELL(submenu), item);  
   g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_undo_changes),  
                    appdata);  
641    
642    /* -------------------- wms submenu -------------------- */  #ifndef UISPECIFIC_MAIN_MENU_IS_MENU_BAR
643      gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());
644    #endif
645    
646    appdata->menu_wms = item = gtk_menu_item_new_with_label( _("WMS") );    appdata->submenu_view = item = gtk_menu_item_new_with_mnemonic( _("_View") );
647    gtk_menu_append(GTK_MENU_SHELL(menu), item);    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
648    submenu = gtk_menu_new();    submenu = gtk_menu_new();
649      gtk_menu_set_accel_group(GTK_MENU(submenu), accel_grp);
650    gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);    gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
651    
652    item = gtk_menu_item_new_with_label( _("Import...") );  #if !defined(USE_HILDON) || (MAEMO_VERSION_MAJOR < 5)
653    gtk_menu_append(GTK_MENU_SHELL(submenu), item);    appdata->menu_item_view_fullscreen = menu_append_new_item(
654    g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_wms_import),      appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_fullscreen), _("_Fullscreen"),
655                     appdata);      GTK_STOCK_FULLSCREEN, "<OSM2Go-Main>/View/Fullscreen",
656        0, 0, TRUE, TRUE, FALSE
657      );
658    #endif
659    
660    appdata->menu_item_wms_clear = item =  #if !defined(ZOOM_BUTTONS) || !defined(USE_HILDON)
661      gtk_menu_item_new_with_label( _("Clear") );    menu_append_new_item(
662    gtk_menu_append(GTK_MENU_SHELL(submenu), item);      appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_zoomin), _("Zoom _in"),
663    gtk_widget_set_sensitive(item, FALSE);      GTK_STOCK_ZOOM_IN, "<OSM2Go-Main>/View/ZoomIn",
664    g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_wms_clear),      GDK_comma, GDK_CONTROL_MASK, TRUE, FALSE, FALSE
665                     appdata);    );
666    
667      menu_append_new_item(
668        appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_zoomout), _("Zoom _out"),
669        GTK_STOCK_ZOOM_OUT, "<OSM2Go-Main>/View/ZoomOut",
670        GDK_period, GDK_CONTROL_MASK, TRUE, FALSE, FALSE
671      );
672    #endif
673    
674      gtk_menu_shell_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new());
675    
676      menu_append_new_item(
677        appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_view_detail_inc), _("More details"),
678        NULL, "<OSM2Go-Main>/View/DetailInc",
679        GDK_period, GDK_MOD1_MASK, TRUE, FALSE, FALSE
680      );
681    
682      menu_append_new_item(
683        appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_view_detail_normal), _("Normal details"),
684        NULL, "<OSM2Go-Main>/View/DetailNormal",
685        0, 0, TRUE, FALSE, FALSE
686      );
687    
688      menu_append_new_item(
689        appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_view_detail_dec), _("Less details"),
690        NULL, "<OSM2Go-Main>/View/DetailDec",
691        GDK_comma, GDK_MOD1_MASK, TRUE, FALSE, FALSE
692      );
693    
694      gtk_menu_shell_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new());
695    
696      appdata->menu_item_map_hide_sel = menu_append_new_item(
697        appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_map_hide_sel), _("_Hide selected"),
698        GTK_STOCK_REMOVE, "<OSM2Go-Main>/View/HideSelected",
699        0, 0, TRUE, FALSE, FALSE
700      );
701      gtk_widget_set_sensitive(appdata->menu_item_map_hide_sel, FALSE);
702    
703      appdata->menu_item_map_show_all = menu_append_new_item(
704        appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_map_show_all), _("_Show all"),
705        GTK_STOCK_ADD, "<OSM2Go-Main>/View/ShowAll",
706        0, 0, TRUE, FALSE, FALSE
707      );
708      gtk_widget_set_sensitive(appdata->menu_item_map_show_all, FALSE);
709    
710      gtk_menu_shell_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new());
711    
712      menu_append_new_item(
713        appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_style), _("St_yle"),
714        GTK_STOCK_SELECT_COLOR, "<OSM2Go-Main>/View/Style",
715        0, 0, TRUE, FALSE, FALSE
716      );
717    
718      gtk_menu_shell_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new());
719    
720      appdata->menu_item_map_no_icons = menu_append_new_item(
721        appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_map_no_icons), _("No _icons"),
722        NULL, "<OSM2Go-Main>/View/NoIcons",
723        0, 0, TRUE, TRUE, appdata->settings->no_icons
724      );
725    
   appdata->menu_item_wms_adjust = item =  
     gtk_menu_item_new_with_label( _("Adjust") );  
   gtk_menu_append(GTK_MENU_SHELL(submenu), item);  
   gtk_widget_set_sensitive(item, FALSE);  
   g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_wms_adjust),  
                    appdata);  
726    
727    /* -------------------- map submenu -------------------- */    /* -------------------- map submenu -------------------- */
728    
729    appdata->menu_map = item = gtk_menu_item_new_with_label( _("Map") );    appdata->submenu_map = item = gtk_menu_item_new_with_mnemonic( _("_Map") );
730    gtk_menu_append(GTK_MENU_SHELL(menu), item);    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
731    submenu = gtk_menu_new();    submenu = gtk_menu_new();
732      gtk_menu_set_accel_group(GTK_MENU(submenu), accel_grp);
733    gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);    gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
734    
735    appdata->menu_item_map_hide_sel = item =    appdata->menu_item_map_upload = menu_append_new_item(
736      gtk_menu_item_new_with_label( _("Hide selected") );      appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_upload), _("_Upload"),
737    gtk_menu_append(GTK_MENU_SHELL(submenu), item);      "upload.16", "<OSM2Go-Main>/Map/Upload",
738    gtk_widget_set_sensitive(item, FALSE);      GDK_u, GDK_SHIFT_MASK|GDK_CONTROL_MASK, TRUE, FALSE, FALSE
739    g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_map_hide_sel),    );
740                     appdata);  
741      menu_append_new_item(
742        appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_download), _("_Download"),
743        "download.16", "<OSM2Go-Main>/Map/Download",
744        GDK_d, GDK_SHIFT_MASK|GDK_CONTROL_MASK, TRUE, FALSE, FALSE
745      );
746    
747      gtk_menu_shell_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new());
748    
749      if(getenv("OSM2GO_UNDO_TEST")) {
750        appdata->menu_item_map_undo = menu_append_new_item(
751                   appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_undo), _("_Undo"),
752                   GTK_STOCK_UNDO, "<OSM2Go-Main>/Map/Undo",
753                   GDK_z, GDK_CONTROL_MASK, TRUE, FALSE, FALSE
754                   );
755      } else
756        printf("set environment variable OSM2GO_UNDO_TEST to enable undo framework tests\n");
757    
758    appdata->menu_item_map_show_all = item =  #ifndef USE_HILDON
759      gtk_menu_item_new_with_label( _("Show all") );    appdata->menu_item_map_save_changes = menu_append_new_item(
760    gtk_menu_append(GTK_MENU_SHELL(submenu), item);      appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_save_changes), _("_Save local changes"),
761    gtk_widget_set_sensitive(item, FALSE);      GTK_STOCK_SAVE, "<OSM2Go-Main>/Map/SaveChanges",
762    g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_map_show_all),      GDK_s, GDK_SHIFT_MASK|GDK_CONTROL_MASK, TRUE, FALSE, FALSE
763                     appdata);    );
764    #endif
765    
766    gtk_menu_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new());    appdata->menu_item_map_undo_changes = menu_append_new_item(
767        appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_undo_changes), _("Undo _all"),
768        GTK_STOCK_DELETE, "<OSM2Go-Main>/Map/UndoAll",
769        0, 0, TRUE, FALSE, FALSE
770      );
771    
772      gtk_menu_shell_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new());
773      appdata->menu_item_map_relations = menu_append_new_item(
774        appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_osm_relations), _("_Relations"),
775        NULL, "<OSM2Go-Main>/Map/Relations",
776        GDK_r, GDK_SHIFT_MASK|GDK_CONTROL_MASK, TRUE, FALSE, FALSE
777      );
778    
779    item = gtk_menu_item_new_with_label( _("Style...") );    /* -------------------- wms submenu -------------------- */
   gtk_menu_append(GTK_MENU_SHELL(submenu), item);  
   g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_style), appdata);  
   
   gtk_menu_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new());  
   
   /* switches mainly intended for testing/debugging */  
   item = gtk_menu_item_new_with_label( _("Redraw") );  
   gtk_menu_append(GTK_MENU_SHELL(submenu), item);  
   g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_redraw), appdata);  
   
   appdata->menu_item_map_no_icons =  
     item = gtk_check_menu_item_new_with_label( _("No Icons") );  
   gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item),  
                                  appdata->settings->no_icons);  
   gtk_menu_append(GTK_MENU_SHELL(submenu), item);  
   g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_map_no_icons),  
                    appdata);  
780    
781    appdata->menu_item_map_no_antialias =    appdata->submenu_wms = item = gtk_menu_item_new_with_mnemonic( _("_WMS") );
782      item = gtk_check_menu_item_new_with_label( _("No Antialias") );    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
783    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item),    submenu = gtk_menu_new();
784                                   appdata->settings->no_antialias);    gtk_menu_set_accel_group(GTK_MENU(submenu), accel_grp);
785    gtk_menu_append(GTK_MENU_SHELL(submenu), item);    gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
786    g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_map_no_antialias),  
787                     appdata);    menu_append_new_item(
788        appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_wms_import), _("_Import"),
789        GTK_STOCK_INDEX, "<OSM2Go-Main>/WMS/Import",
790        0, 0, TRUE, FALSE, FALSE
791      );
792    
793      appdata->menu_item_wms_clear = menu_append_new_item(
794        appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_wms_clear), _("_Clear"),
795        GTK_STOCK_CLEAR, "<OSM2Go-Main>/WMS/Clear",
796        0, 0, TRUE, FALSE, FALSE
797      );
798      gtk_widget_set_sensitive(appdata->menu_item_wms_clear, FALSE);
799    
800      appdata->menu_item_wms_adjust = menu_append_new_item(
801        appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_wms_adjust), _("_Adjust"),
802        NULL, "<OSM2Go-Main>/WMS/Adjust",
803        0, 0, TRUE, FALSE, FALSE
804      );
805      gtk_widget_set_sensitive(appdata->menu_item_wms_adjust, FALSE);
806    
807    /* -------------------- track submenu -------------------- */    /* -------------------- track submenu -------------------- */
808    
809    appdata->track.menu_track = item = gtk_menu_item_new_with_label(_("Track"));    appdata->track.submenu_track = item =
810    gtk_menu_append(GTK_MENU_SHELL(menu), item);      gtk_menu_item_new_with_mnemonic(_("_Track"));
811      gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
812    submenu = gtk_menu_new();    submenu = gtk_menu_new();
813      gtk_menu_set_accel_group(GTK_MENU(submenu), accel_grp);
814    gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);    gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
815    
816    appdata->track.menu_item_import =    appdata->track.menu_item_track_import = menu_append_new_item(
817      item = gtk_menu_item_new_with_label( _("Import...") );      appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_track_import), _("_Import"),
818    gtk_menu_append(GTK_MENU_SHELL(submenu), item);      NULL, "<OSM2Go-Main>/Track/Import",
819    g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_track_import),      0, 0, TRUE, FALSE, FALSE
820                     appdata);    );
821    
822    appdata->track.menu_item_export =    appdata->track.menu_item_track_export = menu_append_new_item(
823      item = gtk_menu_item_new_with_label( _("Export...") );      appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_track_export), _("_Export"),
824    gtk_menu_append(GTK_MENU_SHELL(submenu), item);      NULL, "<OSM2Go-Main>/Track/Export",
825    g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_track_export),      0, 0, FALSE, FALSE, FALSE
826                     appdata);    );
827    
828    appdata->track.menu_item_clear =    appdata->track.menu_item_track_clear = menu_append_new_item(
829      item = gtk_menu_item_new_with_label( _("Clear") );      appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_track_clear), _("_Clear"),
830    gtk_menu_append(GTK_MENU_SHELL(submenu), item);      GTK_STOCK_CLEAR, "<OSM2Go-Main>/Track/Clear",
831    g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_track_clear),      0, 0, FALSE, FALSE, FALSE
832                     appdata);    );
833    
834    appdata->track.menu_item_gps =  
835      item = gtk_check_menu_item_new_with_label( _("GPS") );    appdata->track.menu_item_track_enable_gps = menu_append_new_item(
836    gtk_menu_append(GTK_MENU_SHELL(submenu), item);      appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_track_enable_gps),_("_GPS enable"),
837    g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_track_gps),      NULL, "<OSM2Go-Main>/Track/GPS",
838                     appdata);      GDK_g, GDK_CONTROL_MASK|GDK_SHIFT_MASK, TRUE, TRUE,
839        appdata->settings->enable_gps
840      );
841    
842      appdata->track.menu_item_track_follow_gps = menu_append_new_item(
843        appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_track_follow_gps), _("GPS follow"),
844        NULL, "<OSM2Go-Main>/Track/Follow",
845        0, 0, appdata->settings->enable_gps, TRUE,
846        appdata->settings->follow_gps
847      );
848    
849    /* ------------------------------------------------------- */    /* ------------------------------------------------------- */
850    
851    gtk_menu_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());    gtk_menu_shell_append(GTK_MENU_SHELL(about_quit_items_menu),
852                            gtk_separator_menu_item_new());
853    
854    item = gtk_menu_item_new_with_label( _("About...") );    menu_append_new_item(
855    gtk_menu_append(GTK_MENU_SHELL(menu), item);      appdata, about_quit_items_menu, GTK_SIGNAL_FUNC(cb_menu_about), _("_About"),
856    g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_about), appdata);      GTK_STOCK_ABOUT, "<OSM2Go-Main>/About",
857        0, 0, TRUE, FALSE, FALSE
858      );
859    
860    #ifndef USE_HILDON
861      menu_append_new_item(
862        appdata, about_quit_items_menu, GTK_SIGNAL_FUNC(cb_menu_quit), _("_Quit"),
863        GTK_STOCK_QUIT, "<OSM2Go-Main>/Quit",
864        0, 0, TRUE, FALSE, FALSE
865      );
866    #endif
867    
868    item = gtk_menu_item_new_with_label( _("Quit") );    gtk_window_add_accel_group(GTK_WINDOW(appdata->window), accel_grp);
   gtk_menu_append(GTK_MENU_SHELL(menu), item);  
   g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_quit), appdata);  
869    
870  #ifdef USE_HILDON  #ifdef USE_HILDON
871    hildon_window_set_menu(appdata->window, GTK_MENU(menu));    hildon_window_set_menu(appdata->window, GTK_MENU(menu));
872  #else  #else
873    /* attach ordinary gtk menu */    GtkWidget *menu_bar = menu;
874    GtkWidget *menu_bar = gtk_menu_bar_new();  
875    #ifndef UISPECIFIC_MAIN_MENU_IS_MENU_BAR
876      // we need to make one first
877      menu_bar = gtk_menu_bar_new();
878    
879    GtkWidget *root_menu = gtk_menu_item_new_with_label (_("Menu"));    GtkWidget *root_menu = gtk_menu_item_new_with_label (_("Menu"));
880    gtk_widget_show(root_menu);    gtk_widget_show(root_menu);
# Line 589  void menu_create(appdata_t *appdata) { Line 883  void menu_create(appdata_t *appdata) {
883    gtk_menu_item_set_submenu(GTK_MENU_ITEM (root_menu), menu);    gtk_menu_item_set_submenu(GTK_MENU_ITEM (root_menu), menu);
884    
885    gtk_widget_show(menu_bar);    gtk_widget_show(menu_bar);
886    #endif //UISPECIFIC_MAIN_MENU_IS_MENU_BAR
887    
888    gtk_box_pack_start(GTK_BOX(appdata->vbox), menu_bar, 0, 0, 0);    gtk_box_pack_start(GTK_BOX(appdata->vbox), menu_bar, 0, 0, 0);
889    
890    #endif //USE_HILDON
891    }
892    
893    void menu_cleanup(appdata_t *appdata) { }
894    
895    #else // !defined(USE_HILDON) || (MAEMO_VERSION_MAJOR < 5)
896    
897    void submenu_entry(appdata_t *appdata, HildonAppMenu *menu,
898                       const char *label, const char *value,
899                       GtkSignalFunc activate_cb) {
900    
901    }
902    
903    typedef struct {
904      const char *label, *value;
905      gboolean enabled;
906      gboolean (*toggle)(appdata_t *appdata);
907      gulong offset;
908      GtkSignalFunc activate_cb;
909    } menu_entry_t;
910    
911    typedef struct {
912      const char *title;
913      const menu_entry_t *menu;
914      int len;
915    } submenu_t;
916    
917    static gboolean no_icon_get_toggle(appdata_t *appdata) {
918      if(!appdata)           return FALSE;
919      if(!appdata->settings) return FALSE;
920      return appdata->settings->no_icons;
921    }
922    
923    static gboolean enable_gps_get_toggle(appdata_t *appdata) {
924      if(!appdata)           return FALSE;
925      if(!appdata->settings) return FALSE;
926      return appdata->settings->enable_gps;
927    }
928    
929    static gboolean follow_gps_get_toggle(appdata_t *appdata) {
930      if(!appdata)           return FALSE;
931      if(!appdata->settings) return FALSE;
932      return appdata->settings->follow_gps;
933    }
934    
935    /* create a HildonAppMenu */
936    static GtkWidget *app_menu_create(appdata_t *appdata,
937                                      const menu_entry_t *menu_entries) {
938      HildonAppMenu *menu = HILDON_APP_MENU(hildon_app_menu_new());
939    
940      while(menu_entries->label) {
941        GtkWidget *button = NULL;
942    
943        if(!menu_entries->toggle) {
944          button = hildon_button_new_with_text(
945                HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH,
946                HILDON_BUTTON_ARRANGEMENT_VERTICAL,
947                _(menu_entries->label), _(menu_entries->value));
948          g_signal_connect_after(button, "clicked",
949                                 menu_entries->activate_cb, appdata);
950        } else {
951          button = hildon_check_button_new(HILDON_SIZE_AUTO);
952          gtk_button_set_label(GTK_BUTTON(button), _(menu_entries->label));
953          printf("requesting check for %s: %p\n", menu_entries->label,
954                 menu_entries->toggle);
955          hildon_check_button_set_active(HILDON_CHECK_BUTTON(button),
956                                         menu_entries->toggle(appdata));
957          g_signal_connect_after(button, "toggled",
958                                 menu_entries->activate_cb, appdata);
959        }
960    
961        hildon_button_set_title_alignment(HILDON_BUTTON(button), 0.5, 0.5);
962        hildon_button_set_value_alignment(HILDON_BUTTON(button), 0.5, 0.5);
963    
964        /* offset to GtkWidget pointer was given -> store pointer */
965        if(menu_entries->offset)
966          *(GtkWidget**)(((void*)appdata)+menu_entries->offset) = button;
967    
968        gtk_widget_set_sensitive(button, menu_entries->enabled);
969    
970        hildon_app_menu_append(menu, GTK_BUTTON(button));
971        menu_entries++;
972      }
973    
974      gtk_widget_show_all(GTK_WIDGET(menu));
975      return GTK_WIDGET(menu);
976    }
977    
978    #ifdef MAEMO5_SUBMENU_POPUP
979    static GtkWidget *app_submenu_create(appdata_t *appdata,
980                                         const submenu_t *submenu) {
981      return app_menu_create(appdata, submenu->menu);
982    }
983    
984    static void submenu_popup(GtkWidget *menu) {
985      GtkWidget *top = hildon_window_stack_peek(hildon_window_stack_get_default());
986    
987    #if 0 // nasty workaround for race condition in hildonappmenu
988      int start, end;
989      GTimeVal tv;
990      g_get_current_time(&tv);
991      start = tv.tv_sec * 1000 + tv.tv_usec / 1000;
992      do {
993        if(gtk_events_pending())
994          while(gtk_events_pending()) {
995            putchar('.'); fflush(stdout);
996            gtk_main_iteration();
997          }
998        else
999          usleep(100);
1000    
1001        g_get_current_time(&tv);
1002        end = tv.tv_sec * 1000 + tv.tv_usec / 1000;
1003      } while(end-start < 500);
1004    #endif
1005    
1006      hildon_app_menu_popup(HILDON_APP_MENU(menu), GTK_WINDOW(top));
1007    }
1008    
1009    static void submenu_cleanup(GtkWidget *menu) {
1010      g_object_unref(menu);
1011    }
1012    #else
1013    #define COLUMNS  2
1014    
1015    void on_submenu_entry_clicked(GtkButton *button, GtkWidget *menu) {
1016    
1017      /* force closing of submenu dialog */
1018      gtk_dialog_response(GTK_DIALOG(menu), GTK_RESPONSE_NONE);
1019      gtk_widget_hide(menu);
1020    
1021      /* let gtk clean up */
1022      while(gtk_events_pending())
1023        gtk_main_iteration();
1024    }
1025    
1026    /* use standard dialog boxes for fremantle submenues */
1027    static GtkWidget *app_submenu_create(appdata_t *appdata,
1028                                         const submenu_t *submenu) {
1029    
1030      /* create a oridinary dialog box */
1031      GtkWidget *dialog = misc_dialog_new(MISC_DIALOG_SMALL, _(submenu->title),
1032                                          GTK_WINDOW(appdata->window), NULL);
1033    
1034      gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
1035    
1036      GtkWidget *table = gtk_table_new(submenu->len/COLUMNS, COLUMNS, TRUE);
1037      int x = 0, y = 0;
1038    
1039      const menu_entry_t *menu_entries = submenu->menu;
1040      while(menu_entries->label) {
1041        GtkWidget *button = NULL;
1042    
1043        if(!menu_entries->toggle) {
1044          button = hildon_button_new_with_text(
1045                HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH,
1046                HILDON_BUTTON_ARRANGEMENT_VERTICAL,
1047                _(menu_entries->label), _(menu_entries->value));
1048    
1049          g_signal_connect(button, "clicked",
1050                           G_CALLBACK(on_submenu_entry_clicked), dialog);
1051    
1052          g_signal_connect(button, "clicked",
1053                           menu_entries->activate_cb, appdata);
1054    
1055          hildon_button_set_title_alignment(HILDON_BUTTON(button), 0.5, 0.5);
1056          hildon_button_set_value_alignment(HILDON_BUTTON(button), 0.5, 0.5);
1057        } else {
1058          button = hildon_check_button_new(HILDON_SIZE_AUTO);
1059          gtk_button_set_label(GTK_BUTTON(button), _(menu_entries->label));
1060          printf("requesting check for %s: %p\n", menu_entries->label,
1061                 menu_entries->toggle);
1062          hildon_check_button_set_active(HILDON_CHECK_BUTTON(button),
1063                                         menu_entries->toggle(appdata));
1064    
1065          g_signal_connect(button, "clicked",
1066                           G_CALLBACK(on_submenu_entry_clicked), dialog);
1067    
1068          g_signal_connect(button, "toggled",
1069                           menu_entries->activate_cb, appdata);
1070    
1071          gtk_button_set_alignment(GTK_BUTTON(button), 0.5, 0.5);
1072        }
1073    
1074        /* offset to GtkWidget pointer was given -> store pointer */
1075        if(menu_entries->offset)
1076          *(GtkWidget**)(((void*)appdata)+menu_entries->offset) = button;
1077    
1078        gtk_widget_set_sensitive(button, menu_entries->enabled);
1079    
1080        gtk_table_attach_defaults(GTK_TABLE(table),  button, x, x+1, y, y+1);
1081    
1082        x++;
1083        if(x == COLUMNS) { x = 0; y++; }
1084    
1085        menu_entries++;
1086      }
1087    
1088    
1089      gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(dialog)->vbox), table);
1090    
1091      return dialog;
1092    }
1093    
1094    /* popup the dialog shaped submenu */
1095    static void submenu_popup(GtkWidget *menu) {
1096      gtk_widget_show_all(menu);
1097      gtk_dialog_run(GTK_DIALOG(menu));
1098      gtk_widget_hide(menu);
1099    }
1100    
1101    static void submenu_cleanup(GtkWidget *menu) {
1102      gtk_widget_destroy(menu);
1103    }
1104  #endif  #endif
1105    
1106    /* the view submenu */
1107    void on_submenu_view_clicked(GtkButton *button, appdata_t *appdata) {
1108      submenu_popup(appdata->app_menu_view);
1109    }
1110    
1111    void on_submenu_map_clicked(GtkButton *button, appdata_t *appdata) {
1112      submenu_popup(appdata->app_menu_map);
1113  }  }
1114    
1115    void on_submenu_wms_clicked(GtkButton *button, appdata_t *appdata) {
1116      submenu_popup(appdata->app_menu_wms);
1117    }
1118    
1119    void on_submenu_track_clicked(GtkButton *button, appdata_t *appdata) {
1120      submenu_popup(appdata->app_menu_track);
1121    }
1122    
1123    #define APP_OFFSET(a)  offsetof(appdata_t, a)
1124    #define SIMPLE_ENTRY(a,b)     { a, NULL, TRUE,   NULL, 0, G_CALLBACK(b) }
1125    #define ENABLED_ENTRY(a,b,c)  { a, NULL, TRUE,  NULL, APP_OFFSET(c), G_CALLBACK(b) }
1126    #define DISABLED_ENTRY(a,b,c) { a, NULL, FALSE,  NULL, APP_OFFSET(c), G_CALLBACK(b) }
1127    #define TOGGLE_ENTRY(a,b,c)   { a, NULL, TRUE, c, 0, G_CALLBACK(b) }
1128    #define DISABLED_TOGGLE_ENTRY(a,b,c,d)  \
1129                                  { a, NULL, FALSE, c, APP_OFFSET(d), G_CALLBACK(b) }
1130    #define ENABLED_TOGGLE_ENTRY(a,b,c,d) \
1131                                  { a, NULL, TRUE, c, APP_OFFSET(d), G_CALLBACK(b) }
1132    #define LAST_ENTRY            { NULL, NULL, FALSE, NULL, 0, NULL }
1133    
1134    /* -- the view submenu -- */
1135    static const menu_entry_t submenu_view_entries[] = {
1136    #ifndef ZOOM_BUTTONS
1137      SIMPLE_ENTRY("Zoom in",         cb_menu_zoomin),
1138      SIMPLE_ENTRY("Zoom out",        cb_menu_zoomout),
1139    #endif
1140      /* --- */
1141      SIMPLE_ENTRY("Style",           cb_menu_style),
1142      /* --- */
1143      SIMPLE_ENTRY("Normal details",  cb_menu_view_detail_normal),
1144      SIMPLE_ENTRY("More details",    cb_menu_view_detail_inc),
1145      SIMPLE_ENTRY("Less details",    cb_menu_view_detail_dec),
1146      /* --- */
1147      DISABLED_ENTRY("Hide selected", cb_menu_map_hide_sel, menu_item_map_hide_sel),
1148      DISABLED_ENTRY("Show all",      cb_menu_map_show_all, menu_item_map_show_all),
1149      /* --- */
1150      TOGGLE_ENTRY("No icons",        cb_menu_map_no_icons, no_icon_get_toggle),
1151    
1152      LAST_ENTRY
1153    };
1154    
1155    static const submenu_t submenu_view = {
1156      "View", submenu_view_entries,
1157      sizeof(submenu_view_entries)/sizeof(menu_entry_t)-1
1158    };
1159    
1160    /* -- the map submenu -- */
1161    static const menu_entry_t submenu_map_entries[] = {
1162      ENABLED_ENTRY("Upload",                cb_menu_upload, menu_item_map_upload),
1163      SIMPLE_ENTRY("Download",               cb_menu_download),
1164      //  ENABLED_ENTRY("Save changes",          cb_menu_save_changes,
1165      //            menu_item_map_save_changes),
1166      ENABLED_ENTRY("Undo all",              cb_menu_undo_changes,
1167                    menu_item_map_undo_changes),
1168      ENABLED_ENTRY("Relations",             cb_menu_osm_relations,
1169                    menu_item_map_relations),
1170    
1171      LAST_ENTRY
1172    };
1173    
1174    static const submenu_t submenu_map = {
1175      "Map", submenu_map_entries,
1176      sizeof(submenu_map_entries)/sizeof(menu_entry_t)-1
1177    };
1178    
1179    /* -- the wms submenu -- */
1180    static const menu_entry_t submenu_wms_entries[] = {
1181      SIMPLE_ENTRY("Import",   cb_menu_wms_import),
1182      DISABLED_ENTRY("Clear",  cb_menu_wms_clear, menu_item_wms_clear),
1183      DISABLED_ENTRY("Adjust", cb_menu_wms_adjust, menu_item_wms_adjust),
1184    
1185      LAST_ENTRY
1186    };
1187    
1188    static const submenu_t submenu_wms = {
1189      "WMS", submenu_wms_entries,
1190      sizeof(submenu_wms_entries)/sizeof(menu_entry_t)-1
1191    };
1192    
1193    /* -- the track submenu -- */
1194    static const menu_entry_t submenu_track_entries[] = {
1195      ENABLED_ENTRY("Import",  cb_menu_track_import, track.menu_item_track_import),
1196      DISABLED_ENTRY("Export", cb_menu_track_export, track.menu_item_track_export),
1197      DISABLED_ENTRY("Clear",  cb_menu_track_clear, track.menu_item_track_clear),
1198      ENABLED_TOGGLE_ENTRY("GPS enable", cb_menu_track_enable_gps,
1199                    enable_gps_get_toggle, track.menu_item_track_enable_gps),
1200      DISABLED_TOGGLE_ENTRY("GPS follow", cb_menu_track_follow_gps,
1201                    follow_gps_get_toggle, track.menu_item_track_follow_gps),
1202    
1203      LAST_ENTRY
1204    };
1205    
1206    static const submenu_t submenu_track = {
1207      "Track", submenu_track_entries,
1208      sizeof(submenu_track_entries)/sizeof(menu_entry_t)-1
1209    };
1210    
1211    
1212    /* -- the applications main menu -- */
1213    static const menu_entry_t main_menu[] = {
1214      SIMPLE_ENTRY("About",   cb_menu_about),
1215      SIMPLE_ENTRY("Project", cb_menu_project_open),
1216      ENABLED_ENTRY("View",   on_submenu_view_clicked,  submenu_view),
1217      ENABLED_ENTRY("Map",    on_submenu_map_clicked,   submenu_map),
1218      ENABLED_ENTRY("WMS",    on_submenu_wms_clicked,   submenu_wms),
1219      ENABLED_ENTRY("Track",  on_submenu_track_clicked, track.submenu_track),
1220    
1221      LAST_ENTRY
1222    };
1223    
1224    void menu_create(appdata_t *appdata) {
1225      HildonAppMenu *menu = HILDON_APP_MENU(hildon_app_menu_new());
1226    
1227      /* build menu/submenus */
1228      menu = HILDON_APP_MENU(app_menu_create(appdata, main_menu));
1229      appdata->app_menu_wms   = app_submenu_create(appdata, &submenu_wms);
1230      g_object_ref(appdata->app_menu_wms);
1231      appdata->app_menu_map   = app_submenu_create(appdata, &submenu_map);
1232      g_object_ref(appdata->app_menu_map);
1233      appdata->app_menu_view  = app_submenu_create(appdata, &submenu_view);
1234      g_object_ref(appdata->app_menu_view);
1235      appdata->app_menu_track = app_submenu_create(appdata, &submenu_track);
1236      g_object_ref(appdata->app_menu_track);
1237    
1238      /* enable/disable some entries according to settings */
1239      if(appdata && appdata->settings)
1240        gtk_widget_set_sensitive(appdata->track.menu_item_track_follow_gps,
1241                                 appdata->settings->enable_gps);
1242    
1243      hildon_window_set_app_menu(HILDON_WINDOW(appdata->window), menu);
1244    }
1245    
1246    void menu_cleanup(appdata_t *appdata) {
1247      submenu_cleanup(appdata->app_menu_view);
1248      submenu_cleanup(appdata->app_menu_map);
1249      submenu_cleanup(appdata->app_menu_wms);
1250      submenu_cleanup(appdata->app_menu_track);
1251    }
1252    #endif
1253    
1254  /********************* end of menu **********************/  /********************* end of menu **********************/
1255    
1256    #ifdef UISPECIFIC_MENU_HAS_ACCELS
1257    #define ACCELS_FILE "accels"
1258    
1259    static void menu_accels_load(appdata_t *appdata) {
1260      char *accels_file = g_strdup_printf("%s/" ACCELS_FILE,
1261                                          appdata->settings->base_path);
1262      gtk_accel_map_load(accels_file);
1263      g_free(accels_file);
1264    }
1265    
1266    static void menu_accels_save(appdata_t *appdata) {
1267      char *accels_file = g_strdup_printf("%s" ACCELS_FILE,
1268                                          appdata->settings->base_path);
1269      gtk_accel_map_save(accels_file);
1270      g_free(accels_file);
1271    }
1272    
1273    #endif
1274    
1275    
1276  void cleanup(appdata_t *appdata) {  void cleanup(appdata_t *appdata) {
1277    #ifdef UISPECIFIC_MENU_HAS_ACCELS
1278      menu_accels_save(appdata);
1279    #endif
1280    
1281    settings_save(appdata->settings);    settings_save(appdata->settings);
1282    
1283  #ifdef USE_HILDON  #ifdef USE_HILDON
# Line 640  void cleanup(appdata_t *appdata) { Line 1321  void cleanup(appdata_t *appdata) {
1321    
1322    project_free(appdata->project);    project_free(appdata->project);
1323    
1324      if(appdata->menu_item_map_undo)
1325        undo_free(appdata->osm, appdata->undo.state);
1326    
1327      menu_cleanup(appdata);
1328    
1329    puts("everything is gone");    puts("everything is gone");
1330  }  }
1331    
# Line 655  gboolean on_window_key_press(GtkWidget * Line 1341  gboolean on_window_key_press(GtkWidget *
1341    appdata_t *appdata = (appdata_t*)data;    appdata_t *appdata = (appdata_t*)data;
1342    int handled = FALSE;    int handled = FALSE;
1343    
1344      //  printf("key event with keyval %x\n", event->keyval);
1345    
1346    // the map handles some keys on its own ...    // the map handles some keys on its own ...
1347    switch(event->keyval) {    switch(event->keyval) {
1348    
1349    #if !defined(USE_HILDON) || (MAEMO_VERSION_MAJOR < 5)
1350  #ifdef USE_HILDON  #ifdef USE_HILDON
1351      /* this is in fact a mapping to GDK_F6 */      /* this is in fact a mapping to GDK_F6 */
1352    case HILDON_HARDKEY_FULLSCREEN:    case HILDON_HARDKEY_FULLSCREEN:
# Line 677  gboolean on_window_key_press(GtkWidget * Line 1366  gboolean on_window_key_press(GtkWidget *
1366    
1367      handled = TRUE;      handled = TRUE;
1368      break;      break;
1369    #endif
1370    }    }
1371    
1372    /* forward unprocessed key presses to map */    /* forward unprocessed key presses to map */
# Line 704  int main(int argc, char *argv[]) { Line 1394  int main(int argc, char *argv[]) {
1394    
1395    g_thread_init(NULL);    g_thread_init(NULL);
1396    
   gps_init(&appdata);  
   
1397    gtk_init (&argc, &argv);    gtk_init (&argc, &argv);
1398    
1399      gps_init(&appdata);
1400    
1401  #ifdef USE_HILDON  #ifdef USE_HILDON
1402    printf("Installing osso context for \"org.harbaum." PACKAGE "\"\n");    printf("Installing osso context for \"org.harbaum." PACKAGE "\"\n");
1403    appdata.osso_context = osso_initialize("org.harbaum."PACKAGE,    appdata.osso_context = osso_initialize("org.harbaum."PACKAGE,
# Line 724  int main(int argc, char *argv[]) { Line 1414  int main(int argc, char *argv[]) {
1414    g_set_application_name("OSM2Go");    g_set_application_name("OSM2Go");
1415    
1416    /* Create HildonWindow and set it to HildonProgram */    /* Create HildonWindow and set it to HildonProgram */
1417    #if MAEMO_VERSION_MAJOR < 5
1418    appdata.window = HILDON_WINDOW(hildon_window_new());    appdata.window = HILDON_WINDOW(hildon_window_new());
1419    #else
1420      appdata.window = HILDON_WINDOW(hildon_stackable_window_new());
1421    #endif
1422    hildon_program_add_window(appdata.program, appdata.window);    hildon_program_add_window(appdata.program, appdata.window);
1423    
1424    #if MAEMO_VERSION_MAJOR == 5
1425      unsigned long val = True;
1426      XChangeProperty(GDK_DISPLAY(),
1427                      GDK_WINDOW_XID(GTK_WIDGET(appdata.window)->window),
1428                      XInternAtom(GDK_DISPLAY(),
1429                                  "_HILDON_ZOOM_KEY_ATOM",
1430                                  False), XA_INTEGER, 32,
1431                      PropModeReplace, (unsigned char *) &val, 1);
1432    #endif
1433    
1434  #else  #else
1435    /* Create a Window. */    /* Create a Window. */
1436    appdata.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);    appdata.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
# Line 748  int main(int argc, char *argv[]) { Line 1453  int main(int argc, char *argv[]) {
1453    
1454    appdata.vbox = gtk_vbox_new(FALSE,0);    appdata.vbox = gtk_vbox_new(FALSE,0);
1455    menu_create(&appdata);    menu_create(&appdata);
1456    #ifdef UISPECIFIC_MENU_HAS_ACCELS
1457      menu_accels_load(&appdata);
1458    #endif
1459    
1460    /* ----------------------- setup main window ---------------- */    /* ----------------------- setup main window ---------------- */
1461    
# Line 766  int main(int argc, char *argv[]) { Line 1474  int main(int argc, char *argv[]) {
1474    }    }
1475    
1476    gtk_box_pack_start(GTK_BOX(vbox), map, TRUE, TRUE, 0);    gtk_box_pack_start(GTK_BOX(vbox), map, TRUE, TRUE, 0);
1477    
1478    #ifdef ZOOM_BUTTONS
1479      GtkWidget *zhbox = gtk_hbox_new(FALSE, 0);
1480    
1481      gtk_box_pack_start_defaults(GTK_BOX(zhbox), statusbar_new(&appdata));
1482    
1483      /* ---- add zoom out button right of statusbar ---- */
1484      appdata.btn_zoom_out = gtk_button_new();
1485      gtk_button_set_image(GTK_BUTTON(appdata.btn_zoom_out),
1486            gtk_image_new_from_stock(GTK_STOCK_ZOOM_OUT, GTK_ICON_SIZE_MENU));
1487      g_signal_connect(appdata.btn_zoom_out, "clicked",
1488                       G_CALLBACK(cb_menu_zoomout), &appdata);
1489      gtk_box_pack_start(GTK_BOX(zhbox), appdata.btn_zoom_out, FALSE, FALSE, 0);
1490    
1491      /* ---- add zoom in button right of statusbar ---- */
1492      appdata.btn_zoom_in = gtk_button_new();
1493      gtk_button_set_image(GTK_BUTTON(appdata.btn_zoom_in),
1494            gtk_image_new_from_stock(GTK_STOCK_ZOOM_IN, GTK_ICON_SIZE_MENU));
1495      g_signal_connect(appdata.btn_zoom_in, "clicked",
1496                       G_CALLBACK(cb_menu_zoomin), &appdata);
1497      gtk_box_pack_start(GTK_BOX(zhbox), appdata.btn_zoom_in, FALSE, FALSE, 0);
1498    
1499    
1500      gtk_box_pack_start(GTK_BOX(vbox), zhbox, FALSE, FALSE, 0);
1501    #else
1502    gtk_box_pack_start(GTK_BOX(vbox), statusbar_new(&appdata), FALSE, FALSE, 0);    gtk_box_pack_start(GTK_BOX(vbox), statusbar_new(&appdata), FALSE, FALSE, 0);
1503    #endif
1504    
1505  #ifndef PORTRAIT  #ifndef PORTRAIT
1506    gtk_box_pack_start(GTK_BOX(hbox), iconbar_new(&appdata), FALSE, FALSE, 0);    gtk_box_pack_start(GTK_BOX(hbox), iconbar_new(&appdata), FALSE, FALSE, 0);
1507  #endif  #endif
   gtk_box_pack_start(GTK_BOX(hbox), gtk_vseparator_new(), FALSE, FALSE, 0);  
1508    gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);    gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
1509    
1510    gtk_box_pack_start(GTK_BOX(appdata.vbox), hbox, TRUE, TRUE, 0);    gtk_box_pack_start(GTK_BOX(appdata.vbox), hbox, TRUE, TRUE, 0);
# Line 784  int main(int argc, char *argv[]) { Line 1517  int main(int argc, char *argv[]) {
1517    
1518    /* let gtk do its thing before loading the data, */    /* let gtk do its thing before loading the data, */
1519    /* so the user sees something */    /* so the user sees something */
1520    while(gtk_events_pending()) {    while(gtk_events_pending())
     putchar('.');  
1521      gtk_main_iteration();      gtk_main_iteration();
   }  
1522    
1523    /* load project if one is specified in the settings */    /* load project if one is specified in the settings */
1524    if(appdata.settings->project)    if(appdata.settings->project)
# Line 795  int main(int argc, char *argv[]) { Line 1526  int main(int argc, char *argv[]) {
1526    
1527    main_ui_enable(&appdata);    main_ui_enable(&appdata);
1528    
1529    /* ------------ jump into main loop ---------------- */    /* start GPS if enabled by config */
1530      if(appdata.settings && appdata.settings->enable_gps)
1531        track_enable_gps(&appdata, TRUE);
1532    
1533      /* again let the ui do its thing */
1534      while(gtk_events_pending())
1535        gtk_main_iteration();
1536    
1537    #if 0  // test overlay
1538      {
1539        GtkWidget *overlay = gtk_window_new(GTK_WINDOW_POPUP);
1540        gtk_window_set_default_size(GTK_WINDOW(overlay), 40, 20);
1541        gtk_window_set_transient_for(GTK_WINDOW(overlay), GTK_WINDOW(appdata.window));
1542        gtk_window_set_keep_above(GTK_WINDOW(overlay), TRUE);
1543        gtk_window_set_destroy_with_parent(GTK_WINDOW(overlay), TRUE);
1544        gtk_window_set_position(GTK_WINDOW(overlay), GTK_WIN_POS_CENTER_ON_PARENT);
1545    
1546        gtk_window_set_gravity(GTK_WINDOW(overlay), GDK_GRAVITY_NORTH_EAST);
1547    
1548        printf("x = %d\n", gdk_screen_width() - overlay->allocation.width);
1549        gtk_window_move(GTK_WINDOW(overlay),
1550                        gdk_screen_width() - overlay->allocation.width, 60);
1551    
1552        gtk_window_set_decorated(GTK_WINDOW(overlay), TRUE);
1553    
1554        /* add some zoom buttons for testing */
1555        GtkWidget *hbox = gtk_hbox_new(TRUE, 0);
1556        gtk_box_pack_start_defaults(GTK_BOX(hbox), gtk_button_new_with_label("+"));
1557        gtk_box_pack_start_defaults(GTK_BOX(hbox), gtk_button_new_with_label("-"));
1558        gtk_container_add(GTK_CONTAINER(overlay), hbox);
1559    
1560        gtk_widget_show_all(overlay);
1561      }
1562    #endif
1563    
1564      /* start to interact with the user now that the gui is running */
1565      if(appdata.settings->first_run_demo) {
1566        messagef(GTK_WIDGET(appdata.window), _("Welcome to OSM2Go"),
1567                 _("This is the first time you run OSM2Go. "
1568                   "A demo project has been loaded to get you "
1569                   "started. You can play around with this demo as much "
1570                   "as you like. However, you cannot upload or download "
1571                   "the demo project.\n\n"
1572                   "In order to start working on real data you'll have "
1573                   "to setup a new project and enter your OSM user name "
1574                   "and password. You'll then be able to download the "
1575                   "latest data from OSM and upload your changes into "
1576                   "the OSM main database."
1577                   ));
1578      }
1579    
1580      /* ------------ jump into main loop ---------------- */
1581    gtk_main();    gtk_main();
1582    
1583    puts("gtk_main() left");    puts("gtk_main() left");
1584    
1585    track_save(appdata.project, appdata.track.track);    track_save(appdata.project, appdata.track.track);
1586      track_clear(&appdata, appdata.track.track);
1587      appdata.track.track = NULL;
1588    
1589    /* save a diff if there are dirty entries */    /* save a diff if there are dirty entries */
1590    diff_save(appdata.project, appdata.osm);    diff_save(appdata.project, appdata.osm);
# Line 810  int main(int argc, char *argv[]) { Line 1593  int main(int argc, char *argv[]) {
1593    
1594    return 0;    return 0;
1595  }  }
1596    
1597    // vim:et:ts=8:sw=2:sts=2:ai

Legend:
Removed from v.24  
changed lines
  Added in v.245