X-Git-Url: http://git.tdb.fi/?p=ext%2Fsubsurface.git;a=blobdiff_plain;f=main.c;h=60f2902e60f685d86b7c6d601f847b963b66a465;hp=df966a7e8b2f9f8ad1d7220db8dc36d6528353fa;hb=618a20ba5f2a9adc0e5a35117535f8eaa9fd34a4;hpb=3cb360b51484f3416289aa52c09d60d87df60027 diff --git a/main.c b/main.c index df966a7..60f2902 100644 --- a/main.c +++ b/main.c @@ -1,3 +1,4 @@ +/* main.c */ #include #include #include @@ -5,15 +6,10 @@ #include "dive.h" #include "divelist.h" -#include "display.h" -GtkWidget *main_window; -GtkWidget *main_vbox; -GtkWidget *error_info_bar; -GtkWidget *error_label; -int error_count; -struct DiveList dive_list; +struct units output_units; +/* random helper functions, used here or elsewhere */ static int sortfn(const void *_a, const void *_b) { const struct dive *a = *(void **)_a; @@ -26,13 +22,93 @@ static int sortfn(const void *_a, const void *_b) return 0; } +const char *weekday(int wday) +{ + static const char wday_array[7][4] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" + }; + return wday_array[wday]; +} + +const char *monthname(int mon) +{ + static const char month_array[12][4] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", + }; + return month_array[mon]; +} + +/* + * When adding dives to the dive table, we try to renumber + * the new dives based on any old dives in the dive table. + * + * But we only do it if: + * + * - the last dive in the old dive table was numbered + * + * - all the new dives are strictly at the end (so the + * "last dive" is at the same location in the dive table + * after re-sorting the dives. + * + * - none of the new dives have any numbers + * + * This catches the common case of importing new dives from + * a dive computer, and gives them proper numbers based on + * your old dive list. But it tries to be very conservative + * and not give numbers if there is *any* question about + * what the numbers should be - in which case you need to do + * a manual re-numbering. + */ +static void try_to_renumber(struct dive *last, int preexisting) +{ + int i, nr; + + /* + * If the new dives aren't all strictly at the end, + * we're going to expect the user to do a manual + * renumbering. + */ + if (get_dive(preexisting-1) != last) + return; + + /* + * If any of the new dives already had a number, + * we'll have to do a manual renumbering. + */ + for (i = preexisting; i < dive_table.nr; i++) { + struct dive *dive = get_dive(i); + if (dive->number) + return; + } + + /* + * Ok, renumber.. + */ + nr = last->number; + for (i = preexisting; i < dive_table.nr; i++) { + struct dive *dive = get_dive(i); + dive->number = ++nr; + } +} + +/* + * track whether we switched to importing dives + */ +static gboolean imported = FALSE; + /* * This doesn't really report anything at all. We just sort the * dives, the GUI does the reporting */ -static void report_dives(void) +void report_dives(gboolean is_imported) { int i; + int preexisting = dive_table.preexisting; + struct dive *last; + + /* This does the right thing for -1: NULL */ + last = get_dive(preexisting-1); qsort(dive_table.dives, dive_table.nr, sizeof(struct dive *), sortfn); @@ -58,6 +134,18 @@ static void report_dives(void) /* Redo the new 'i'th dive */ i--; } + + if (is_imported) { + /* Was the previous dive table state numbered? */ + if (last && last->number) + try_to_renumber(last, preexisting); + + /* did we have dives in the table and added more? */ + if (last && preexisting != dive_table.nr) + mark_divelist_changed(TRUE); + } + dive_table.preexisting = dive_table.nr; + dive_list_update_dives(); } static void parse_argument(const char *arg) @@ -69,6 +157,22 @@ static void parse_argument(const char *arg) case 'v': verbose++; continue; + case '-': + /* long options with -- */ + if (strcmp(arg,"--import") == 0) { + /* mark the dives so far as the base, + * everything after is imported */ + report_dives(FALSE); + imported = TRUE; + return; + } + /* fallthrough */ + case 'p': + /* ignore process serial number argument when run as native macosx app */ + if (strncmp(arg, "-psn_", 5) == 0) { + return; + } + /* fallthrough */ default: fprintf(stderr, "Bad argument '%s'\n", arg); exit(1); @@ -76,226 +180,43 @@ static void parse_argument(const char *arg) } while (*++p); } -static void on_destroy(GtkWidget* w, gpointer data) +void update_dive(struct dive *new_dive) { - gtk_main_quit(); -} - -static GtkWidget *dive_profile; - -void repaint_dive(void) -{ - update_dive_info(current_dive); - gtk_widget_queue_draw(dive_profile); -} - -static char *existing_filename; - -static void on_info_bar_response(GtkWidget *widget, gint response, - gpointer data) -{ - if (response == GTK_RESPONSE_OK) - { - gtk_widget_destroy(widget); - error_info_bar = NULL; - } -} + static struct dive *buffered_dive; + struct dive *old_dive = buffered_dive; -static void report_error(GError* error) -{ - if (error == NULL) - { - return; + if (old_dive) { + flush_divelist(old_dive); } - - if (error_info_bar == NULL) - { - error_count = 1; - error_info_bar = gtk_info_bar_new_with_buttons(GTK_STOCK_OK, - GTK_RESPONSE_OK, - NULL); - g_signal_connect(error_info_bar, "response", G_CALLBACK(on_info_bar_response), NULL); - gtk_info_bar_set_message_type(GTK_INFO_BAR(error_info_bar), - GTK_MESSAGE_ERROR); - - error_label = gtk_label_new(error->message); - GtkWidget *container = gtk_info_bar_get_content_area(GTK_INFO_BAR(error_info_bar)); - gtk_container_add(GTK_CONTAINER(container), error_label); - - gtk_box_pack_start(GTK_BOX(main_vbox), error_info_bar, FALSE, FALSE, 0); - gtk_widget_show_all(main_vbox); - } - else - { - error_count++; - char buffer[256]; - snprintf(buffer, sizeof(buffer), "Failed to open %i files.", error_count); - gtk_label_set(GTK_LABEL(error_label), buffer); + if (new_dive) { + show_dive_info(new_dive); + show_dive_equipment(new_dive); + show_dive_stats(new_dive); } + buffered_dive = new_dive; } -static void file_open(GtkWidget *w, gpointer data) +void renumber_dives(int nr) { - GtkWidget *dialog; - dialog = gtk_file_chooser_dialog_new("Open File", - GTK_WINDOW(main_window), - GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, - NULL); - gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE); - - if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { - GSList *filenames; - char *filename; - filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog)); - - GError *error = NULL; - while(filenames != NULL) { - filename = (char *)filenames->data; - parse_xml_file(filename, &error); - if (error != NULL) - { - report_error(error); - g_error_free(error); - error = NULL; - } - - g_free(filename); - filenames = g_slist_next(filenames); - } - g_slist_free(filenames); - report_dives(); - repaint_dive(); - dive_list_update_dives(dive_list); - } - gtk_widget_destroy(dialog); -} + int i; -static void file_save(GtkWidget *w, gpointer data) -{ - GtkWidget *dialog; - dialog = gtk_file_chooser_dialog_new("Save File", - GTK_WINDOW(main_window), - GTK_FILE_CHOOSER_ACTION_SAVE, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, - NULL); - gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE); - if (!existing_filename) { - gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), "Untitled document"); - } else - gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), existing_filename); - - if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { - char *filename; - filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); - save_dives(filename); - g_free(filename); + for (i = 0; i < dive_table.nr; i++) { + struct dive *dive = dive_table.dives[i]; + dive->number = nr + i; + flush_divelist(dive); } - gtk_widget_destroy(dialog); -} - -static void quit(GtkWidget *w, gpointer data) -{ - gtk_main_quit(); -} - -static GtkActionEntry menu_items[] = { - { "FileMenuAction", GTK_STOCK_FILE, "Log", NULL, NULL, NULL}, - { "OpenFile", GTK_STOCK_OPEN, NULL, "O", NULL, G_CALLBACK(file_open) }, - { "SaveFile", GTK_STOCK_SAVE, NULL, "S", NULL, G_CALLBACK(file_save) }, - { "Quit", GTK_STOCK_QUIT, NULL, "Q", NULL, G_CALLBACK(quit) }, -}; -static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]); - -static const gchar* ui_string = " \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ -"; - -static GtkWidget *get_menubar_menu(GtkWidget *window) -{ - GtkActionGroup *action_group = gtk_action_group_new("Menu"); - gtk_action_group_add_actions(action_group, menu_items, nmenu_items, 0); - - GtkUIManager *ui_manager = gtk_ui_manager_new(); - gtk_ui_manager_insert_action_group(ui_manager, action_group, 0); - GError* error = 0; - gtk_ui_manager_add_ui_from_string(GTK_UI_MANAGER(ui_manager), ui_string, -1, &error); - - gtk_window_add_accel_group(GTK_WINDOW(window), gtk_ui_manager_get_accel_group(ui_manager)); - GtkWidget* menu = gtk_ui_manager_get_widget(ui_manager, "/MainMenu"); - - return menu; + mark_divelist_changed(TRUE); } int main(int argc, char **argv) { int i; - GtkWidget *win; - GtkWidget *paned; - GtkWidget *info_box; - GtkWidget *notebook; - GtkWidget *frame; - GtkWidget *dive_info; - GtkWidget *menubar; - GtkWidget *vbox; - - parse_xml_init(); - - gtk_init(&argc, &argv); - - error_info_bar = NULL; - win = gtk_window_new(GTK_WINDOW_TOPLEVEL); - g_signal_connect(G_OBJECT(win), "destroy", G_CALLBACK(on_destroy), NULL); - main_window = win; - vbox = gtk_vbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(win), vbox); - main_vbox = vbox; + output_units = SI_units; - menubar = get_menubar_menu(win); - gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0); - - /* HPane for left the dive list, and right the dive info */ - paned = gtk_hpaned_new(); - gtk_box_pack_end(GTK_BOX(vbox), paned, TRUE, TRUE, 0); - - /* Create the actual divelist */ - dive_list = dive_list_create(); - gtk_paned_add1(GTK_PANED(paned), dive_list.container_widget); - - /* VBox for dive info, and tabs */ - info_box = gtk_vbox_new(FALSE, 6); - gtk_paned_add2(GTK_PANED(paned), info_box); - - /* Frame for minimal dive info */ - frame = dive_info_frame(); - gtk_box_pack_start(GTK_BOX(info_box), frame, FALSE, TRUE, 6); - - /* Notebook for dive info vs profile vs .. */ - notebook = gtk_notebook_new(); - gtk_box_pack_start(GTK_BOX(info_box), notebook, TRUE, TRUE, 6); - - /* Frame for dive profile */ - dive_profile = dive_profile_widget(); - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dive_profile, gtk_label_new("Dive Profile")); - - /* Frame for extended dive info */ - dive_info = extended_dive_info_widget(); - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dive_info, gtk_label_new("Extended Dive Info")); + parse_xml_init(); - gtk_widget_set_app_paintable(win, TRUE); - gtk_widget_show_all(win); + init_ui(&argc, &argv); for (i = 1; i < argc; i++) { const char *a = argv[i]; @@ -305,7 +226,7 @@ int main(int argc, char **argv) continue; } GError *error = NULL; - parse_xml_file(a, &error); + parse_file(a, &error); if (error != NULL) { @@ -315,9 +236,9 @@ int main(int argc, char **argv) } } - report_dives(); - dive_list_update_dives(dive_list); + report_dives(imported); - gtk_main(); + run_ui(); + exit_ui(); return 0; }