--- trunk/src/main.c 2008/12/21 11:49:35 24 +++ trunk/src/main.c 2009/07/06 15:51:30 189 @@ -1,4 +1,6 @@ /* + * Copyright (C) 2008 Till Harbaum . + * * This file is part of OSM2Go. * * OSM2Go is free software: you can redistribute it and/or modify @@ -21,7 +23,14 @@ #include #include +#if defined(USE_HILDON) && (MAEMO_VERSION_MAJOR == 5) +#include +#include +#include +#endif + #include "appdata.h" +#include "banner.h" /* disable/enable main screen control dependant on presence of open project */ static void main_ui_enable(appdata_t *appdata) { @@ -33,7 +42,12 @@ map_action_cancel(appdata); /* ---- set project name as window title ----- */ -#ifndef USE_HILDON +#if defined(USE_HILDON) && MAEMO_VERSION_MAJOR < 5 + if(project_valid) + gtk_window_set_title(GTK_WINDOW(appdata->window), appdata->project->name); + else + gtk_window_set_title(GTK_WINDOW(appdata->window), ""); +#else char *str = NULL; if(project_valid) str = g_strdup_printf("OSM2Go - %s", appdata->project->name); @@ -42,26 +56,22 @@ gtk_window_set_title(GTK_WINDOW(appdata->window), 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), ""); #endif if(appdata->iconbar && appdata->iconbar->toolbar) gtk_widget_set_sensitive(appdata->iconbar->toolbar, osm_valid); /* disable all menu entries related to map */ - gtk_widget_set_sensitive(appdata->menu_osm, project_valid); - gtk_widget_set_sensitive(appdata->menu_item_osm_upload, osm_valid); - gtk_widget_set_sensitive(appdata->menu_item_osm_diff, osm_valid); - gtk_widget_set_sensitive(appdata->menu_item_osm_undo_changes, osm_valid); - gtk_widget_set_sensitive(appdata->track.menu_track, osm_valid); - gtk_widget_set_sensitive(appdata->menu_view, osm_valid); - gtk_widget_set_sensitive(appdata->menu_wms, osm_valid); - gtk_widget_set_sensitive(appdata->menu_map, osm_valid); - gtk_widget_set_sensitive(appdata->menu_item_project_close, project_valid); + gtk_widget_set_sensitive(appdata->submenu_map, project_valid); + gtk_widget_set_sensitive(appdata->menu_item_map_upload, osm_valid); + if(appdata->menu_item_map_undo) + gtk_widget_set_sensitive(appdata->menu_item_map_undo, osm_valid); + gtk_widget_set_sensitive(appdata->menu_item_map_save_changes, osm_valid); + gtk_widget_set_sensitive(appdata->menu_item_map_undo_changes, osm_valid); + gtk_widget_set_sensitive(appdata->menu_item_map_relations, osm_valid); + gtk_widget_set_sensitive(appdata->track.submenu_track, osm_valid); + gtk_widget_set_sensitive(appdata->submenu_view, osm_valid); + gtk_widget_set_sensitive(appdata->submenu_wms, osm_valid); if(!project_valid) statusbar_set(appdata, _("Please load or create a project"), FALSE); @@ -69,80 +79,72 @@ /******************** begin of menu *********************/ -#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 - static void -cb_menu_project_open(GtkWidget *window, gpointer data) { +cb_menu_project_open(GtkMenuItem *item, gpointer data) { appdata_t *appdata = (appdata_t*)data; project_load(appdata, NULL); main_ui_enable(appdata); } static void -cb_menu_project_close(GtkWidget *window, gpointer data) { +cb_menu_project_wizard(GtkMenuItem *item, gpointer data) { appdata_t *appdata = (appdata_t*)data; - project_close(appdata); - main_ui_enable(appdata); + project_wizard(appdata); } static void -cb_menu_about(GtkWidget *window, gpointer data) { - GtkAboutDialog *about = GTK_ABOUT_DIALOG(gtk_about_dialog_new()); - - gtk_about_dialog_set_name(about, "OSM2Go"); - gtk_about_dialog_set_version(about, VERSION); - gtk_about_dialog_set_copyright(about, _("Copyright 2008")); +cb_menu_about(GtkMenuItem *item, gpointer data) { + appdata_t *appdata = (appdata_t*)data; const gchar *authors[] = { "Till Harbaum ", - "Andrew Chadwick", + "Andrew Chadwick ", NULL }; - gtk_about_dialog_set_authors(about, authors); - - gtk_about_dialog_set_website(about, - _("http://www.harbaum.org/till/maemo")); - - gtk_about_dialog_set_comments(about, - _("Mobile OSM Editor")); + const gchar *artists[] = { + "Andrew Zhilin ", + NULL }; - gtk_widget_show_all(GTK_WIDGET(about)); - gtk_dialog_run(GTK_DIALOG(about)); - gtk_widget_destroy(GTK_WIDGET(about)); + gtk_show_about_dialog(GTK_WINDOW(appdata->window), + "name", "OSM2Go", + "version", VERSION, + "copyright", _("Copyright 2008-2009"), + "authors", authors, + "artists", artists, + "website", _("http://www.harbaum.org/till/maemo"), + "comments", _("Mobile OSM Editor"), + NULL); } void on_window_destroy (GtkWidget *widget, gpointer data); +#ifndef USE_HILDON static void -cb_menu_quit(GtkWidget *window, gpointer data) { +cb_menu_quit(GtkMenuItem *item, gpointer data) { appdata_t *appdata = (appdata_t*)data; gtk_widget_destroy(GTK_WIDGET(appdata->window)); } +#endif static void -cb_menu_upload(GtkWidget *window, gpointer data) { +cb_menu_upload(GtkMenuItem *item, gpointer data) { appdata_t *appdata = (appdata_t*)data; if(!appdata->osm || !appdata->project) return; + if(project_check_demo(GTK_WIDGET(appdata->window), appdata->project)) + return; + osm_upload(appdata, appdata->osm, appdata->project); } static void -cb_menu_download(GtkWidget *window, gpointer data) { +cb_menu_download(GtkMenuItem *item, gpointer data) { appdata_t *appdata = (appdata_t*)data; if(!appdata->project) return; + if(project_check_demo(GTK_WIDGET(appdata->window), appdata->project)) + return; + /* if we have valid osm data loaded: save state first */ if(appdata->osm) { /* redraw the entire map by destroying all map items and redrawing them */ @@ -154,29 +156,32 @@ } // download - if(osm_download(GTK_WIDGET(appdata->window), appdata->project)) { - appdata->osm = osm_parse(appdata->project->osm); + if(osm_download(GTK_WIDGET(appdata->window), appdata->settings, + appdata->project)) { + banner_busy_start(appdata, 1, "Redrawing"); + appdata->osm = osm_parse(appdata->project->path, appdata->project->osm); diff_restore(appdata, appdata->project, appdata->osm); map_paint(appdata); + banner_busy_stop(appdata); //"Redrawing" } main_ui_enable(appdata); } static void -cb_menu_wms_import(GtkWidget *window, gpointer data) { +cb_menu_wms_import(GtkMenuItem *item, gpointer data) { appdata_t *appdata = (appdata_t*)data; wms_import(appdata); } static void -cb_menu_wms_clear(GtkWidget *window, gpointer data) { +cb_menu_wms_clear(GtkMenuItem *item, gpointer data) { appdata_t *appdata = (appdata_t*)data; wms_remove(appdata); } static void -cb_menu_wms_adjust(GtkWidget *window, gpointer data) { +cb_menu_wms_adjust(GtkMenuItem *item, gpointer data) { appdata_t *appdata = (appdata_t*)data; map_action_set(appdata, MAP_ACTION_BG_ADJUST); } @@ -184,110 +189,103 @@ /* ----------- hide objects for performance reasons ----------- */ static void -cb_menu_map_hide_sel(GtkWidget *window, gpointer data) { +cb_menu_map_hide_sel(GtkMenuItem *item, gpointer data) { appdata_t *appdata = (appdata_t*)data; map_hide_selected(appdata); } static void -cb_menu_map_show_all(GtkWidget *window, gpointer data) { +cb_menu_map_show_all(GtkMenuItem *item, gpointer data) { appdata_t *appdata = (appdata_t*)data; map_show_all(appdata); } /* ---------------------------------------------------------- */ -#if 1 // mainly for testing -static void -cb_menu_redraw(GtkWidget *window, gpointer data) { - appdata_t *appdata = (appdata_t*)data; +#if defined(USE_HILDON) && (MAEMO_VERSION_MAJOR == 5) +#define MENU_CHECK_ITEM HildonCheckButton +#define MENU_CHECK_ITEM_ACTIVE(a) hildon_check_button_get_active(a) +#else +#define MENU_CHECK_ITEM GtkCheckMenuItem +#define MENU_CHECK_ITEM_ACTIVE(a) gtk_check_menu_item_get_active(a) +#endif - /* redraw the entire map by destroying all map items and redrawing them */ - track_save(appdata->project, appdata->track.track); - diff_save(appdata->project, appdata->osm); - map_clear(appdata, MAP_LAYER_ALL); - osm_free(&appdata->icon, appdata->osm); +static void +cb_menu_map_no_icons(MENU_CHECK_ITEM *item, appdata_t *appdata) { - appdata->osm = osm_parse(appdata->project->osm); - diff_restore(appdata, appdata->project, appdata->osm); - map_paint(appdata); + banner_busy_start(appdata, 1, "Redrawing"); + map_clear(appdata, MAP_LAYER_OBJECTS_ONLY); - appdata->track.track = track_restore(appdata, appdata->project); - if(appdata->track.track) - map_track_draw(appdata->map, appdata->track.track); + appdata->settings->no_icons = MENU_CHECK_ITEM_ACTIVE(item); - wms_load(appdata); + map_paint(appdata); + banner_busy_stop(appdata); //"Redrawing" } -#endif static void -cb_menu_style(GtkWidget *widget, gpointer data) { +cb_menu_style(GtkMenuItem *item, gpointer data) { appdata_t *appdata = (appdata_t*)data; style_select(GTK_WIDGET(appdata->window), appdata); } static void -cb_menu_map_no_icons(GtkWidget *widget, gpointer data) { +cb_menu_undo(GtkMenuItem *item, gpointer data) { appdata_t *appdata = (appdata_t*)data; - map_clear(appdata, MAP_LAYER_OBJECTS_ONLY); - appdata->settings->no_icons = - gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)); - map_paint(appdata); -} + undo(appdata); -static void -cb_menu_map_no_antialias(GtkWidget *widget, gpointer data) { - appdata_t *appdata = (appdata_t*)data; - - map_clear(appdata, MAP_LAYER_OBJECTS_ONLY); - appdata->settings->no_antialias = - gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)); - map_paint(appdata); + // the banner will be displayed from within undo with more details } static void -cb_menu_save_changes(GtkWidget *widget, gpointer data) { +cb_menu_save_changes(GtkMenuItem *item, gpointer data) { appdata_t *appdata = (appdata_t*)data; diff_save(appdata->project, appdata->osm); - statusbar_set(appdata, _("Saved all changes made " - "to this project so far"), FALSE); + banner_show_info(appdata, _("Saved local changes")); } static void -cb_menu_undo_changes(GtkWidget *widget, gpointer data) { +cb_menu_undo_changes(GtkMenuItem *item, gpointer data) { appdata_t *appdata = (appdata_t*)data; if(!yes_no_f(GTK_WIDGET(appdata->window), NULL, 0, 0, - _("Undo all changes?"), - _("Do you really want to undo all your changes " - "not uploaded so far? This cannot be undone!"))) + _("Discard local changes?"), + _("Throw away all the changes you've not " + "uploaded yet? This can't be undone."))) return; - + + banner_busy_start(appdata, 1, _("Redrawing")); map_clear(appdata, MAP_LAYER_OBJECTS_ONLY); osm_free(&appdata->icon, appdata->osm); diff_remove(appdata->project); - appdata->osm = osm_parse(appdata->project->osm); + appdata->osm = osm_parse(appdata->project->path, appdata->project->osm); map_paint(appdata); + banner_busy_stop(appdata); //"Redrawing" - statusbar_set(appdata, _("All changes made " - "so far have been reset"), FALSE); + banner_show_info(appdata, _("Discarded local changes")); } static void -cb_menu_fullscreen(GtkWidget *widget, gpointer data) { +cb_menu_osm_relations(GtkMenuItem *item, gpointer data) { + relation_list((appdata_t*)data); +} + +#if !defined(USE_HILDON) || (MAEMO_VERSION_MAJOR < 5) +static void +cb_menu_fullscreen(MENU_CHECK_ITEM *item, gpointer data) { appdata_t *appdata = (appdata_t *)data; - if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) + if(MENU_CHECK_ITEM_ACTIVE(item)) gtk_window_fullscreen(GTK_WINDOW(appdata->window)); else gtk_window_unfullscreen(GTK_WINDOW(appdata->window)); } +#endif static void -cb_menu_zoomin(GtkWidget *widget, appdata_t *appdata) { +cb_menu_zoomin(GtkMenuItem *item, appdata_t *appdata) { if(!appdata || !appdata->map) return; map_set_zoom(appdata->map, appdata->map->state->zoom*ZOOM_FACTOR_MENU, TRUE); @@ -295,7 +293,7 @@ } static void -cb_menu_zoomout(GtkWidget *widget, appdata_t *appdata) { +cb_menu_zoomout(GtkMenuItem *item, appdata_t *appdata) { if(!appdata || !appdata->map) return; map_set_zoom(appdata->map, appdata->map->state->zoom/ZOOM_FACTOR_MENU, TRUE); @@ -303,7 +301,32 @@ } static void -cb_menu_track_import(GtkWidget *window, appdata_t *appdata) { +cb_menu_view_detail_inc(GtkMenuItem *item, gpointer data) { + appdata_t *appdata = (appdata_t*)data; + + printf("detail level increase\n"); + map_detail_increase(appdata->map); +} + +static void +cb_menu_view_detail_normal(GtkMenuItem *item, gpointer data) { + appdata_t *appdata = (appdata_t*)data; + + printf("detail level normal\n"); + map_detail_normal(appdata->map); +} + +static void +cb_menu_view_detail_dec(GtkMenuItem *item, gpointer data) { + appdata_t *appdata = (appdata_t*)data; + + printf("detail level decrease\n"); + map_detail_decrease(appdata->map); +} + +static void +cb_menu_track_import(GtkMenuItem *item, appdata_t *appdata) { + g_assert(appdata->settings); /* open a file selector */ GtkWidget *dialog; @@ -320,30 +343,35 @@ NULL); #endif - /* use path if one is present */ - if(appdata->track.import_path) - gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), - appdata->track.import_path); - + if(appdata->settings->track_path) { + if(!g_file_test(appdata->settings->track_path, G_FILE_TEST_EXISTS)) { + char *last_sep = strrchr(appdata->settings->track_path, '/'); + if(last_sep) { + *last_sep = 0; // seperate path from file + + /* the user just created a new document */ + gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), + appdata->settings->track_path); + gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), + last_sep+1); + + /* restore full filename */ + *last_sep = '/'; + } + } else + gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), + appdata->settings->track_path); + } + gtk_widget_show_all (GTK_WIDGET(dialog)); if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_FM_OK) { char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); /* load a track */ - track_do(appdata, TRACK_IMPORT, filename); + appdata->track.track = track_import(appdata, filename); if(appdata->track.track) { - - /* save path if gpx was successfully loaded */ - 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 = '/'; - } + if(appdata->settings->track_path) g_free(appdata->settings->track_path); + appdata->settings->track_path = g_strdup(filename); } g_free (filename); } @@ -352,235 +380,468 @@ } static void -cb_menu_track_gps(GtkWidget *window, gpointer data) { - appdata_t *appdata = (appdata_t*)data; +cb_menu_track_enable_gps(MENU_CHECK_ITEM *item, appdata_t *appdata) { + track_enable_gps(appdata, MENU_CHECK_ITEM_ACTIVE(item)); +} - if(gtk_check_menu_item_get_active( - GTK_CHECK_MENU_ITEM(appdata->track.menu_item_gps))) { - track_do(appdata, TRACK_GPS, NULL); - } else { - track_do(appdata, TRACK_NONE, NULL); - } + +static void +cb_menu_track_follow_gps(MENU_CHECK_ITEM *item, appdata_t *appdata) { + appdata->settings->follow_gps = MENU_CHECK_ITEM_ACTIVE(item); } + static void -cb_menu_track_export(GtkWidget *window, gpointer data) { - appdata_t *appdata = (appdata_t*)data; - messagef(GTK_WIDGET(appdata->window), _("NIY"), - _("Track export is not yet supported.")); +cb_menu_track_export(GtkMenuItem *item, appdata_t *appdata) { + g_assert(appdata->settings); + + /* open a file selector */ + GtkWidget *dialog; + +#ifdef USE_HILDON + dialog = hildon_file_chooser_dialog_new(GTK_WINDOW(appdata->window), + GTK_FILE_CHOOSER_ACTION_SAVE); +#else + dialog = gtk_file_chooser_dialog_new(_("Export track file"), + GTK_WINDOW(appdata->window), + GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, + NULL); +#endif + + printf("set filename <%s>\n", appdata->settings->track_path); + + if(appdata->settings->track_path) { + if(!g_file_test(appdata->settings->track_path, G_FILE_TEST_EXISTS)) { + char *last_sep = strrchr(appdata->settings->track_path, '/'); + if(last_sep) { + *last_sep = 0; // seperate path from file + + /* the user just created a new document */ + gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), + appdata->settings->track_path); + gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), + last_sep+1); + + /* restore full filename */ + *last_sep = '/'; + } + } else + gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), + appdata->settings->track_path); + } + + if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_FM_OK) { + gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + if(filename) { + printf("export to %s\n", filename); + + if(!g_file_test(filename, G_FILE_TEST_EXISTS) || + yes_no_f(dialog, appdata, MISC_AGAIN_ID_EXPORT_OVERWRITE, + MISC_AGAIN_FLAG_DONT_SAVE_NO, + "Overwrite existing file", + "The file already exists. " + "Do you really want to replace it?")) { + if(appdata->settings->track_path) + g_free(appdata->settings->track_path); + appdata->settings->track_path = g_strdup(filename); + + track_export(appdata, filename); + } + } + } + + gtk_widget_destroy (dialog); } + static void -cb_menu_track_clear(GtkWidget *window, gpointer data) { +cb_menu_track_clear(GtkMenuItem *item, gpointer data) { appdata_t *appdata = (appdata_t*)data; - track_do(appdata, TRACK_NONE, NULL); + track_clear(appdata, appdata->track.track); + appdata->track.track = NULL; } -void menu_create(appdata_t *appdata) { - GtkWidget *menu, *item, *submenu; - menu = gtk_menu_new(); - /* -------------------- Project submenu -------------------- */ - item = gtk_menu_item_new_with_label( _("Project") ); - gtk_menu_append(GTK_MENU_SHELL(menu), item); - submenu = gtk_menu_new(); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu); +/* + * Platform-specific UI tweaks. + */ - 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); - appdata->menu_item_project_close = item = - gtk_menu_item_new_with_label( _("Close") ); - gtk_menu_append(GTK_MENU_SHELL(submenu), item); - g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_project_close), - appdata); +#ifndef USE_HILDON +#ifdef PORTRAIT - /* --------------- view menu ------------------- */ +// Portrait mode, for openmoko-like systems +#define uispecific_main_menu_new gtk_menu_new - gtk_menu_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new()); +#else - appdata->menu_view = item = - gtk_menu_item_new_with_label( _("View") ); - gtk_menu_append(GTK_MENU_SHELL(menu), item); - submenu = gtk_menu_new(); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu); - - appdata->menu_item_view_fullscreen = - item = gtk_check_menu_item_new_with_label( _("Fullscreen") ); - gtk_menu_append(GTK_MENU_SHELL(submenu), item); - g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_fullscreen), +// Regular desktop builds +#define uispecific_main_menu_new gtk_menu_bar_new +#define UISPECIFIC_MAIN_MENU_IS_MENU_BAR +#define UISPECIFIC_MENU_HAS_ICONS +#define UISPECIFIC_MENU_HAS_ACCELS + +#endif //PORTRAIT +#else//USE_HILDON + +// Maemo/Hildon builds +#define uispecific_main_menu_new gtk_menu_new + +#endif + + +#if !defined(USE_HILDON) || (MAEMO_VERSION_MAJOR < 5) +// Half-arsed slapdash common menu item constructor. Let's use GtkBuilder +// instead so we have some flexibility. + +static GtkWidget * +menu_append_new_item(appdata_t *appdata, + GtkWidget *menu_shell, + GtkSignalFunc activate_cb, + char *label, + const gchar *icon_name, // stock id or name for icon_load + // overridden by label, accels, icon_name + const gchar *accel_path, + guint accel_key, // from gdk/gdkkeysyms.h + GdkModifierType accel_mods, // e.g. GDK_CONTROL_MASK + gboolean enabled, + gboolean is_check, gboolean check_status) +{ + GtkWidget *item = NULL; + GtkWidget *image = NULL; + + gboolean stock_item_known = FALSE; + GtkStockItem stock_item; + if (icon_name != NULL) { + stock_item_known = gtk_stock_lookup(icon_name, &stock_item); + } + + // Icons +#ifndef UISPECIFIC_MENU_HAS_ICONS + item = is_check ? gtk_check_menu_item_new_with_mnemonic (label) + : gtk_menu_item_new_with_mnemonic (label); +#else + if (is_check) { + item = gtk_check_menu_item_new_with_mnemonic (label); + } + else if (!stock_item_known) { + GdkPixbuf *pbuf = icon_load(&appdata->icon, icon_name); + if (pbuf) { + image = gtk_image_new_from_pixbuf(pbuf); + } + if (image) { + item = gtk_image_menu_item_new_with_mnemonic(label); + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image); + } + else { + item = gtk_menu_item_new_with_mnemonic(label); + } + } + else { + item = gtk_image_menu_item_new_with_mnemonic(label); + image = gtk_image_new_from_stock(icon_name, GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image); + } +#endif + +#ifdef UISPECIFIC_MENU_HAS_ACCELS + // Accelerators + // Default + if (accel_path != NULL) { + gtk_menu_item_set_accel_path(GTK_MENU_ITEM(item), accel_path); + if (accel_key != 0) { + gtk_accel_map_add_entry( accel_path, accel_key, accel_mods ); + } + else if (stock_item_known) { + gtk_accel_map_add_entry( accel_path, stock_item.keyval, + stock_item.modifier ); + } + } +#endif + + gtk_menu_shell_append(GTK_MENU_SHELL(menu_shell), GTK_WIDGET(item)); + gtk_widget_set_sensitive(GTK_WIDGET(item), enabled); + if (is_check) + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), check_status); + + g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(activate_cb), appdata); + return item; +} + +void menu_create(appdata_t *appdata) { + GtkWidget *menu, *item, *submenu; + GtkWidget *about_quit_items_menu; - item = gtk_menu_item_new_with_label( _("Zoom +" )); - gtk_menu_append(GTK_MENU_SHELL(submenu), item); - g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_zoomin), appdata); - - item = gtk_menu_item_new_with_label( _("Zoom -") ); - gtk_menu_append(GTK_MENU_SHELL(submenu), item); - g_signal_connect(item, "activate", - GTK_SIGNAL_FUNC(cb_menu_zoomout), appdata); + if (g_module_supported()) { + printf("*** can use GModule: consider using GtkUIManager / GtkBuilder\n"); + } - /* -------------------- OSM submenu -------------------- */ + menu = uispecific_main_menu_new(); + about_quit_items_menu = menu; - appdata->menu_osm = item = gtk_menu_item_new_with_label( _("OSM") ); - gtk_menu_append(GTK_MENU_SHELL(menu), item); + /* -------------------- Project submenu -------------------- */ + + GtkAccelGroup *accel_grp = gtk_accel_group_new(); + item = gtk_menu_item_new_with_mnemonic( _("_Project") ); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); submenu = gtk_menu_new(); + gtk_menu_set_accel_group(GTK_MENU(submenu), accel_grp); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu); +#ifdef UISPECIFIC_MAIN_MENU_IS_MENU_BAR + about_quit_items_menu = submenu; +#endif - appdata->menu_item_osm_upload = item = - gtk_menu_item_new_with_label( _("Upload...") ); - gtk_menu_append(GTK_MENU_SHELL(submenu), item); - g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_upload), appdata); - - item = gtk_menu_item_new_with_label( _("Download...") ); - gtk_menu_append(GTK_MENU_SHELL(submenu), item); - g_signal_connect(item, "activate", - GTK_SIGNAL_FUNC(cb_menu_download), appdata); - - gtk_menu_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new()); - - appdata->menu_item_osm_diff = item = - gtk_menu_item_new_with_label( _("Save diff file") ); - gtk_menu_append(GTK_MENU_SHELL(submenu), item); - g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_save_changes), - appdata); + menu_append_new_item( + appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_project_open), _("_Open"), + GTK_STOCK_OPEN, "/Project/Open", + 0, 0, TRUE, FALSE, FALSE + ); + + menu_append_new_item( + appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_project_wizard), _("_Wizard"), + GTK_STOCK_NEW, "/Project/Wizard", + 0, 0, TRUE, FALSE, FALSE + ); - appdata->menu_item_osm_undo_changes = item = - 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); + /* --------------- view menu ------------------- */ - /* -------------------- wms submenu -------------------- */ +#ifndef UISPECIFIC_MAIN_MENU_IS_MENU_BAR + gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new()); +#endif - appdata->menu_wms = item = gtk_menu_item_new_with_label( _("WMS") ); - gtk_menu_append(GTK_MENU_SHELL(menu), item); + appdata->submenu_view = item = gtk_menu_item_new_with_mnemonic( _("_View") ); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); submenu = gtk_menu_new(); + gtk_menu_set_accel_group(GTK_MENU(submenu), accel_grp); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu); - item = gtk_menu_item_new_with_label( _("Import...") ); - gtk_menu_append(GTK_MENU_SHELL(submenu), item); - g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_wms_import), - appdata); +#if !defined(USE_HILDON) || (MAEMO_VERSION_MAJOR < 5) + appdata->menu_item_view_fullscreen = menu_append_new_item( + appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_fullscreen), _("_Fullscreen"), + GTK_STOCK_FULLSCREEN, "/View/Fullscreen", + 0, 0, TRUE, TRUE, FALSE + ); +#endif - appdata->menu_item_wms_clear = item = - gtk_menu_item_new_with_label( _("Clear") ); - 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_clear), - appdata); + menu_append_new_item( + appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_zoomin), _("Zoom _in"), + GTK_STOCK_ZOOM_IN, "/View/ZoomIn", + GDK_comma, GDK_CONTROL_MASK, TRUE, FALSE, FALSE + ); + + menu_append_new_item( + appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_zoomout), _("Zoom _out"), + GTK_STOCK_ZOOM_OUT, "/View/ZoomOut", + GDK_period, GDK_CONTROL_MASK, TRUE, FALSE, FALSE + ); + + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new()); + + menu_append_new_item( + appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_view_detail_inc), _("More details"), + NULL, "/View/DetailInc", + GDK_period, GDK_MOD1_MASK, TRUE, FALSE, FALSE + ); + + menu_append_new_item( + appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_view_detail_normal), _("Normal details"), + NULL, "/View/DetailNormal", + 0, 0, TRUE, FALSE, FALSE + ); + + menu_append_new_item( + appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_view_detail_dec), _("Less details"), + NULL, "/View/DetailDec", + GDK_comma, GDK_MOD1_MASK, TRUE, FALSE, FALSE + ); + + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new()); + + appdata->menu_item_map_hide_sel = menu_append_new_item( + appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_map_hide_sel), _("_Hide selected"), + GTK_STOCK_REMOVE, "/View/HideSelected", + 0, 0, TRUE, FALSE, FALSE + ); + gtk_widget_set_sensitive(appdata->menu_item_map_hide_sel, FALSE); + + appdata->menu_item_map_show_all = menu_append_new_item( + appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_map_show_all), _("_Show all"), + GTK_STOCK_ADD, "/View/ShowAll", + 0, 0, TRUE, FALSE, FALSE + ); + gtk_widget_set_sensitive(appdata->menu_item_map_show_all, FALSE); + + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new()); + + menu_append_new_item( + appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_style), _("St_yle"), + GTK_STOCK_SELECT_COLOR, "/View/Style", + 0, 0, TRUE, FALSE, FALSE + ); + + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new()); + + appdata->menu_item_map_no_icons = menu_append_new_item( + appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_map_no_icons), _("No _icons"), + NULL, "/View/NoIcons", + 0, 0, TRUE, TRUE, appdata->settings->no_icons + ); - 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); /* -------------------- map submenu -------------------- */ - appdata->menu_map = item = gtk_menu_item_new_with_label( _("Map") ); - gtk_menu_append(GTK_MENU_SHELL(menu), item); + appdata->submenu_map = item = gtk_menu_item_new_with_mnemonic( _("_Map") ); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); submenu = gtk_menu_new(); + gtk_menu_set_accel_group(GTK_MENU(submenu), accel_grp); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu); - appdata->menu_item_map_hide_sel = item = - gtk_menu_item_new_with_label( _("Hide selected") ); - gtk_menu_append(GTK_MENU_SHELL(submenu), item); - gtk_widget_set_sensitive(item, FALSE); - g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_map_hide_sel), - appdata); - - appdata->menu_item_map_show_all = item = - gtk_menu_item_new_with_label( _("Show all") ); - gtk_menu_append(GTK_MENU_SHELL(submenu), item); - gtk_widget_set_sensitive(item, FALSE); - g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_map_show_all), - appdata); - - gtk_menu_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new()); + appdata->menu_item_map_upload = menu_append_new_item( + appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_upload), _("_Upload"), + "upload.16", "/Map/Upload", + GDK_u, GDK_SHIFT_MASK|GDK_CONTROL_MASK, TRUE, FALSE, FALSE + ); + + menu_append_new_item( + appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_download), _("_Download"), + "download.16", "/Map/Download", + GDK_d, GDK_SHIFT_MASK|GDK_CONTROL_MASK, TRUE, FALSE, FALSE + ); + + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new()); + + if(getenv("OSM2GO_UNDO_TEST")) { + appdata->menu_item_map_undo = menu_append_new_item( + appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_undo), _("_Undo"), + GTK_STOCK_UNDO, "/Map/Undo", + GDK_z, GDK_CONTROL_MASK, TRUE, FALSE, FALSE + ); + } else + printf("set environment variable OSM2GO_UNDO_TEST to enable undo framework tests\n"); + + appdata->menu_item_map_save_changes = menu_append_new_item( + appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_save_changes), _("_Save local changes"), + GTK_STOCK_SAVE, "/Map/SaveChanges", + GDK_s, GDK_SHIFT_MASK|GDK_CONTROL_MASK, TRUE, FALSE, FALSE + ); + + appdata->menu_item_map_undo_changes = menu_append_new_item( + appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_undo_changes), _("Disca_rd local changes"), + GTK_STOCK_DELETE, "/Map/DiscardChanges", + 0, 0, TRUE, FALSE, FALSE + ); + + gtk_menu_shell_append(GTK_MENU_SHELL(submenu), gtk_separator_menu_item_new()); + appdata->menu_item_map_relations = menu_append_new_item( + appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_osm_relations), _("_Relations"), + NULL, "/Map/Relations", + GDK_r, GDK_SHIFT_MASK|GDK_CONTROL_MASK, TRUE, FALSE, FALSE + ); - item = gtk_menu_item_new_with_label( _("Style...") ); - 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); + /* -------------------- wms submenu -------------------- */ - appdata->menu_item_map_no_antialias = - item = gtk_check_menu_item_new_with_label( _("No Antialias") ); - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), - appdata->settings->no_antialias); - gtk_menu_append(GTK_MENU_SHELL(submenu), item); - g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_map_no_antialias), - appdata); + appdata->submenu_wms = item = gtk_menu_item_new_with_mnemonic( _("_WMS") ); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + submenu = gtk_menu_new(); + gtk_menu_set_accel_group(GTK_MENU(submenu), accel_grp); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu); + + menu_append_new_item( + appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_wms_import), _("_Import"), + GTK_STOCK_INDEX, "/WMS/Import", + 0, 0, TRUE, FALSE, FALSE + ); + + appdata->menu_item_wms_clear = menu_append_new_item( + appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_wms_clear), _("_Clear"), + GTK_STOCK_CLEAR, "/WMS/Clear", + 0, 0, TRUE, FALSE, FALSE + ); + gtk_widget_set_sensitive(appdata->menu_item_wms_clear, FALSE); + + appdata->menu_item_wms_adjust = menu_append_new_item( + appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_wms_adjust), _("_Adjust"), + NULL, "/WMS/Adjust", + 0, 0, TRUE, FALSE, FALSE + ); + gtk_widget_set_sensitive(appdata->menu_item_wms_adjust, FALSE); /* -------------------- track submenu -------------------- */ - appdata->track.menu_track = item = gtk_menu_item_new_with_label(_("Track")); - gtk_menu_append(GTK_MENU_SHELL(menu), item); + appdata->track.submenu_track = item = + gtk_menu_item_new_with_mnemonic(_("_Track")); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); submenu = gtk_menu_new(); + gtk_menu_set_accel_group(GTK_MENU(submenu), accel_grp); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu); - appdata->track.menu_item_import = - item = gtk_menu_item_new_with_label( _("Import...") ); - gtk_menu_append(GTK_MENU_SHELL(submenu), item); - g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_track_import), - appdata); - - appdata->track.menu_item_export = - item = gtk_menu_item_new_with_label( _("Export...") ); - gtk_menu_append(GTK_MENU_SHELL(submenu), item); - g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_track_export), - appdata); - - appdata->track.menu_item_clear = - item = gtk_menu_item_new_with_label( _("Clear") ); - gtk_menu_append(GTK_MENU_SHELL(submenu), item); - g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_track_clear), - appdata); - - appdata->track.menu_item_gps = - item = gtk_check_menu_item_new_with_label( _("GPS") ); - gtk_menu_append(GTK_MENU_SHELL(submenu), item); - g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_track_gps), - appdata); + appdata->track.menu_item_track_import = menu_append_new_item( + appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_track_import), _("_Import"), + NULL, "/Track/Import", + 0, 0, TRUE, FALSE, FALSE + ); + + appdata->track.menu_item_track_export = menu_append_new_item( + appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_track_export), _("_Export"), + NULL, "/Track/Export", + 0, 0, FALSE, FALSE, FALSE + ); + + appdata->track.menu_item_track_clear = menu_append_new_item( + appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_track_clear), _("_Clear"), + GTK_STOCK_CLEAR, "/Track/Clear", + 0, 0, FALSE, FALSE, FALSE + ); + + + appdata->track.menu_item_track_enable_gps = menu_append_new_item( + appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_track_enable_gps),_("_GPS enable"), + NULL, "/Track/GPS", + GDK_g, GDK_CONTROL_MASK|GDK_SHIFT_MASK, TRUE, TRUE, + appdata->settings->enable_gps + ); + + appdata->track.menu_item_track_follow_gps = menu_append_new_item( + appdata, submenu, GTK_SIGNAL_FUNC(cb_menu_track_follow_gps), _("GPS follow"), + NULL, "/Track/Follow", + 0, 0, appdata->settings->enable_gps, TRUE, + appdata->settings->follow_gps + ); /* ------------------------------------------------------- */ - gtk_menu_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new()); - + gtk_menu_shell_append(GTK_MENU_SHELL(about_quit_items_menu), + gtk_separator_menu_item_new()); - item = gtk_menu_item_new_with_label( _("About...") ); - gtk_menu_append(GTK_MENU_SHELL(menu), item); - g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_about), appdata); + menu_append_new_item( + appdata, about_quit_items_menu, GTK_SIGNAL_FUNC(cb_menu_about), _("_About"), + GTK_STOCK_ABOUT, "/About", + 0, 0, TRUE, FALSE, FALSE + ); +#ifndef USE_HILDON + menu_append_new_item( + appdata, about_quit_items_menu, GTK_SIGNAL_FUNC(cb_menu_quit), _("_Quit"), + GTK_STOCK_QUIT, "/Quit", + 0, 0, TRUE, FALSE, FALSE + ); +#endif - item = gtk_menu_item_new_with_label( _("Quit") ); - gtk_menu_append(GTK_MENU_SHELL(menu), item); - g_signal_connect(item, "activate", GTK_SIGNAL_FUNC(cb_menu_quit), appdata); + gtk_window_add_accel_group(GTK_WINDOW(appdata->window), accel_grp); #ifdef USE_HILDON hildon_window_set_menu(appdata->window, GTK_MENU(menu)); #else - /* attach ordinary gtk menu */ - GtkWidget *menu_bar = gtk_menu_bar_new(); + GtkWidget *menu_bar = menu; + +#ifndef UISPECIFIC_MAIN_MENU_IS_MENU_BAR + // we need to make one first + menu_bar = gtk_menu_bar_new(); GtkWidget *root_menu = gtk_menu_item_new_with_label (_("Menu")); gtk_widget_show(root_menu); @@ -589,14 +850,173 @@ gtk_menu_item_set_submenu(GTK_MENU_ITEM (root_menu), menu); gtk_widget_show(menu_bar); +#endif //UISPECIFIC_MAIN_MENU_IS_MENU_BAR + gtk_box_pack_start(GTK_BOX(appdata->vbox), menu_bar, 0, 0, 0); -#endif + +#endif //USE_HILDON +} +#else // !defined(USE_HILDON) || (MAEMO_VERSION_MAJOR < 5) + +void submenu_entry(appdata_t *appdata, HildonAppMenu *menu, + const char *label, const char *value, + GtkSignalFunc activate_cb) { + } +typedef struct { + const char *label, *value; + gboolean enabled; + gboolean (*toggle)(appdata_t *appdata); + gulong offset; + GtkSignalFunc activate_cb; +} menu_entry_t; + +static gboolean no_icon_get_toggle(appdata_t *appdata) { + if(!appdata) return FALSE; + if(!appdata->settings) return FALSE; + return appdata->settings->no_icons; +} + +/* create a HildonAppMenu */ +static GtkWidget *app_menu_create(appdata_t *appdata, const menu_entry_t *menu_entries) { + HildonAppMenu *menu = HILDON_APP_MENU(hildon_app_menu_new()); + + while(menu_entries->label) { + GtkWidget *button = NULL; + + if(!menu_entries->toggle) { + button = hildon_button_new_with_text( + HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH, + HILDON_BUTTON_ARRANGEMENT_VERTICAL, + _(menu_entries->label), menu_entries->value); + g_signal_connect_after(button, "clicked", menu_entries->activate_cb, appdata); + } else { + button = hildon_check_button_new(HILDON_SIZE_AUTO); + gtk_button_set_label(GTK_BUTTON(button), _(menu_entries->label)); + hildon_check_button_set_active(HILDON_CHECK_BUTTON(button), + menu_entries->toggle(appdata)); + g_signal_connect_after(button, "toggled", menu_entries->activate_cb, appdata); + } + + /* offset to GtkWidget pointer was given -> store pointer */ + if(menu_entries->offset) + *(GtkWidget**)(((void*)appdata)+menu_entries->offset) = button; + + gtk_widget_set_sensitive(button, menu_entries->enabled); + + hildon_app_menu_append(menu, GTK_BUTTON(button)); + menu_entries++; + } + + gtk_widget_show_all(GTK_WIDGET(menu)); + return GTK_WIDGET(menu); +} + +/* the view submenu */ +void on_submenu_view_clicked(GtkButton *button, appdata_t *appdata) { + /* draw a popup menu. */ + hildon_app_menu_popup(HILDON_APP_MENU(appdata->submenu_view), + GTK_WINDOW(appdata->window)); +} + +void on_submenu_wms_clicked(GtkButton *button, appdata_t *appdata) { + /* draw a popup menu. */ + hildon_app_menu_popup(HILDON_APP_MENU(appdata->submenu_wms), + GTK_WINDOW(appdata->window)); +} + +/* -- the view submenu -- */ +#define APP_OFFSET(a) offsetof(appdata_t, a) +#define SIMPLE_ENTRY(a,b) { a, NULL, TRUE, NULL, 0, G_CALLBACK(b) } +#define DISABLED_ENTRY(a,b,c) { a, NULL, FALSE, NULL, APP_OFFSET(c), G_CALLBACK(b) } +#define LAST_ENTRY { NULL, NULL, FALSE, NULL, 0, NULL } + +static const menu_entry_t submenu_view[] = { + SIMPLE_ENTRY("Zoom in", cb_menu_zoomin), + SIMPLE_ENTRY("Zoom out", cb_menu_zoomout), + /* --- */ + SIMPLE_ENTRY("Style", cb_menu_style), + /* --- */ + SIMPLE_ENTRY("Normal details", cb_menu_view_detail_normal), + SIMPLE_ENTRY("More details", cb_menu_view_detail_inc), + SIMPLE_ENTRY("Less details", cb_menu_view_detail_dec), + /* --- */ + DISABLED_ENTRY("Hide selected", cb_menu_map_hide_sel, menu_item_map_hide_sel), + DISABLED_ENTRY("Show all", cb_menu_map_show_all, menu_item_map_show_all), + /* --- */ + { "No icons", NULL, TRUE, no_icon_get_toggle, 0, G_CALLBACK(cb_menu_map_no_icons) }, + + LAST_ENTRY +}; + +/* -- the wms submenu -- */ +static const menu_entry_t submenu_wms[] = { + SIMPLE_ENTRY("Import", cb_menu_wms_import), + DISABLED_ENTRY("Clear", cb_menu_wms_clear, menu_item_wms_clear), + DISABLED_ENTRY("Adjust", cb_menu_wms_adjust, menu_item_wms_adjust), + + LAST_ENTRY +}; + +void menu_create(appdata_t *appdata) { + GtkWidget *button; + HildonAppMenu *menu = HILDON_APP_MENU(hildon_app_menu_new()); + + /* build submenus */ + appdata->submenu_wms = app_menu_create(appdata, submenu_wms); + appdata->submenu_view = app_menu_create(appdata, submenu_view); + + /* ------- */ + button = gtk_button_new_with_label(_("About")); + g_signal_connect_after(button, "clicked", + G_CALLBACK(cb_menu_about), appdata); + hildon_app_menu_append(menu, GTK_BUTTON(button)); + + button = gtk_button_new_with_label(_("View")); + g_signal_connect_after(button, "clicked", + G_CALLBACK(on_submenu_view_clicked), appdata); + hildon_app_menu_append(menu, GTK_BUTTON(button)); + + button = gtk_button_new_with_label(_("WMS")); + g_signal_connect_after(button, "clicked", + G_CALLBACK(on_submenu_wms_clicked), appdata); + hildon_app_menu_append(menu, GTK_BUTTON(button)); + + + + gtk_widget_show_all(GTK_WIDGET(menu)); + hildon_window_set_app_menu(HILDON_WINDOW(appdata->window), menu); +} +#endif + /********************* end of menu **********************/ +#ifdef UISPECIFIC_MENU_HAS_ACCELS +#define ACCELS_FILE "accels" + +static void menu_accels_load(appdata_t *appdata) { + char *accels_file = g_strdup_printf("%s/" ACCELS_FILE, + appdata->settings->base_path); + gtk_accel_map_load(accels_file); + g_free(accels_file); +} + +static void menu_accels_save(appdata_t *appdata) { + char *accels_file = g_strdup_printf("%s" ACCELS_FILE, + appdata->settings->base_path); + gtk_accel_map_save(accels_file); + g_free(accels_file); +} + +#endif + void cleanup(appdata_t *appdata) { +#ifdef UISPECIFIC_MENU_HAS_ACCELS + menu_accels_save(appdata); +#endif + settings_save(appdata->settings); #ifdef USE_HILDON @@ -640,6 +1060,9 @@ project_free(appdata->project); + if(appdata->menu_item_map_undo) + undo_free(appdata->undo.state); + puts("everything is gone"); } @@ -658,6 +1081,7 @@ // the map handles some keys on its own ... switch(event->keyval) { +#if !defined(USE_HILDON) || (MAEMO_VERSION_MAJOR < 5) #ifdef USE_HILDON /* this is in fact a mapping to GDK_F6 */ case HILDON_HARDKEY_FULLSCREEN: @@ -677,6 +1101,7 @@ handled = TRUE; break; +#endif } /* forward unprocessed key presses to map */ @@ -704,10 +1129,10 @@ g_thread_init(NULL); - gps_init(&appdata); - gtk_init (&argc, &argv); + gps_init(&appdata); + #ifdef USE_HILDON printf("Installing osso context for \"org.harbaum." PACKAGE "\"\n"); appdata.osso_context = osso_initialize("org.harbaum."PACKAGE, @@ -748,6 +1173,9 @@ appdata.vbox = gtk_vbox_new(FALSE,0); menu_create(&appdata); +#ifdef UISPECIFIC_MENU_HAS_ACCELS + menu_accels_load(&appdata); +#endif /* ----------------------- setup main window ---------------- */ @@ -765,13 +1193,24 @@ return -1; } +#if 0 // another test overlay + { + GtkWidget *fixed = gtk_fixed_new(); + + gtk_fixed_put(GTK_FIXED(fixed), gtk_label_new("Nase"), 0,0); + gtk_fixed_put(GTK_FIXED(fixed), map, 0,0); + + gtk_box_pack_start(GTK_BOX(vbox), fixed, TRUE, TRUE, 0); + } +#else gtk_box_pack_start(GTK_BOX(vbox), map, TRUE, TRUE, 0); +#endif + gtk_box_pack_start(GTK_BOX(vbox), statusbar_new(&appdata), FALSE, FALSE, 0); #ifndef PORTRAIT gtk_box_pack_start(GTK_BOX(hbox), iconbar_new(&appdata), FALSE, FALSE, 0); #endif - gtk_box_pack_start(GTK_BOX(hbox), gtk_vseparator_new(), FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(appdata.vbox), hbox, TRUE, TRUE, 0); @@ -784,10 +1223,8 @@ /* let gtk do its thing before loading the data, */ /* so the user sees something */ - while(gtk_events_pending()) { - putchar('.'); + while(gtk_events_pending()) gtk_main_iteration(); - } /* load project if one is specified in the settings */ if(appdata.settings->project) @@ -795,13 +1232,58 @@ main_ui_enable(&appdata); - /* ------------ jump into main loop ---------------- */ + /* start GPS if enabled by config */ + if(appdata.settings && appdata.settings->enable_gps) + track_enable_gps(&appdata, TRUE); + + /* again let the ui do its thing */ + while(gtk_events_pending()) + gtk_main_iteration(); + +#if 0 // test overlay + { + GtkWidget *overlay = gtk_window_new(GTK_WINDOW_POPUP); + gtk_window_set_default_size(GTK_WINDOW(overlay), 40, 20); + gtk_window_set_transient_for(GTK_WINDOW(overlay), GTK_WINDOW(appdata.window)); + gtk_window_set_keep_above(GTK_WINDOW(overlay), TRUE); + gtk_window_set_destroy_with_parent(GTK_WINDOW(overlay), TRUE); + gtk_window_set_position(GTK_WINDOW(overlay), GTK_WIN_POS_CENTER_ON_PARENT); + gtk_window_set_decorated(GTK_WINDOW(overlay), TRUE); + + /* add some zoom buttons for testing */ + GtkWidget *hbox = gtk_hbox_new(TRUE, 0); + gtk_box_pack_start_defaults(GTK_BOX(hbox), gtk_button_new_with_label("+")); + gtk_box_pack_start_defaults(GTK_BOX(hbox), gtk_button_new_with_label("-")); + gtk_container_add(GTK_CONTAINER(overlay), hbox); + gtk_widget_show_all(overlay); + } +#endif + + /* start to interact with the user now that the gui is running */ + if(appdata.settings->first_run_demo) { + messagef(GTK_WIDGET(appdata.window), _("Welcome to OSM2Go"), + _("This is the first time you run OSM2Go. " + "A demo project has been loaded to get you " + "started. You can play around with this demo as much " + "as you like. However, you cannot upload or download " + "the demo project.\n\n" + "In order to start working on real data you'll have " + "to setup a new project and enter your OSM user name " + "and password. You'll then be able to download the " + "latest data from OSM and upload your changes into " + "the OSM main database." + )); + } + + /* ------------ jump into main loop ---------------- */ gtk_main(); puts("gtk_main() left"); track_save(appdata.project, appdata.track.track); + track_clear(&appdata, appdata.track.track); + appdata.track.track = NULL; /* save a diff if there are dirty entries */ diff_save(appdata.project, appdata.osm); @@ -810,3 +1292,5 @@ return 0; } + +// vim:et:ts=8:sw=2:sts=2:ai