X-Git-Url: http://git.tdb.fi/?p=ext%2Fsubsurface.git;a=blobdiff_plain;f=gtk-gui.c;h=bdf2952f074faf5a7c2efaf767f3696421dad7a7;hp=e16d60e2d410630e1c1c8a45be45941c5443ef29;hb=618a20ba5f2a9adc0e5a35117535f8eaa9fd34a4;hpb=c544226334ec1bfaac1c8d649722bb17728606e1 diff --git a/gtk-gui.c b/gtk-gui.c index e16d60e..bdf2952 100644 --- a/gtk-gui.c +++ b/gtk-gui.c @@ -31,6 +31,45 @@ static GtkWidget *dive_profile; visible_cols_t visible_cols = {TRUE, FALSE}; +static const char *default_dive_computer_vendor; +static const char *default_dive_computer_product; +static const char *default_dive_computer_device; + +static int is_default_dive_computer(const char *vendor, const char *product) +{ + return default_dive_computer_vendor && !strcmp(vendor, default_dive_computer_vendor) && + default_dive_computer_product && !strcmp(product, default_dive_computer_product); +} + +static int is_default_dive_computer_device(const char *name) +{ + return default_dive_computer_device && !strcmp(name, default_dive_computer_device); +} + +static void set_default_dive_computer(const char *vendor, const char *product) +{ + if (!vendor || !*vendor) + return; + if (!product || !*product) + return; + if (is_default_dive_computer(vendor, product)) + return; + default_dive_computer_vendor = vendor; + default_dive_computer_product = product; + subsurface_set_conf("dive_computer_vendor", PREF_STRING, vendor); + subsurface_set_conf("dive_computer_product", PREF_STRING, product); +} + +static void set_default_dive_computer_device(const char *name) +{ + if (!name || !*name) + return; + if (is_default_dive_computer_device(name)) + return; + default_dive_computer_device = name; + subsurface_set_conf("dive_computer_device", PREF_STRING, name); +} + void repaint_dive(void) { update_dive(current_dive); @@ -114,7 +153,7 @@ static void file_open(GtkWidget *w, gpointer data) GError *error = NULL; while(filenames != NULL) { filename = filenames->data; - parse_xml_file(filename, &error); + parse_file(filename, &error); if (error != NULL) { report_error(error); @@ -296,6 +335,8 @@ UNITCALLBACK(set_liter, volume, LITER) UNITCALLBACK(set_cuft, volume, CUFT) UNITCALLBACK(set_celsius, temperature, CELSIUS) UNITCALLBACK(set_fahrenheit, temperature, FAHRENHEIT) +UNITCALLBACK(set_kg, weight, KG) +UNITCALLBACK(set_lbs, weight, LBS) #define OPTIONCALLBACK(name, option) \ static void name(GtkWidget *w, gpointer data) \ @@ -357,6 +398,11 @@ static void preferences_dialog(GtkWidget *w, gpointer data) "Fahrenheit", set_fahrenheit, (output_units.temperature == FAHRENHEIT), NULL); + create_radio(box, "Weight:", + "kg", set_kg, (output_units.weight == KG), + "lbs", set_lbs, (output_units.weight == LBS), + NULL); + frame = gtk_frame_new("Columns"); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), frame, FALSE, FALSE, 5); @@ -409,13 +455,16 @@ static void preferences_dialog(GtkWidget *w, gpointer data) subsurface_set_conf("psi", PREF_BOOL, BOOL_TO_PTR(output_units.pressure == PSI)); subsurface_set_conf("cuft", PREF_BOOL, BOOL_TO_PTR(output_units.volume == CUFT)); subsurface_set_conf("fahrenheit", PREF_BOOL, BOOL_TO_PTR(output_units.temperature == FAHRENHEIT)); + subsurface_set_conf("lbs", PREF_BOOL, BOOL_TO_PTR(output_units.weight == LBS)); subsurface_set_conf("TEMPERATURE", PREF_BOOL, BOOL_TO_PTR(visible_cols.temperature)); subsurface_set_conf("CYLINDER", PREF_BOOL, BOOL_TO_PTR(visible_cols.cylinder)); subsurface_set_conf("NITROX", PREF_BOOL, BOOL_TO_PTR(visible_cols.nitrox)); subsurface_set_conf("SAC", PREF_BOOL, BOOL_TO_PTR(visible_cols.sac)); subsurface_set_conf("OTU", PREF_BOOL, BOOL_TO_PTR(visible_cols.otu)); subsurface_set_conf("divelist_font", PREF_STRING, divelist_font); - subsurface_close_conf(); + + /* Flush the changes out to the system */ + subsurface_flush_conf(); } gtk_widget_destroy(dialog); } @@ -560,11 +609,13 @@ static void view_info(GtkWidget *w, gpointer data) gtk_paned_set_position(GTK_PANED(hpane), 65535); } -/* Ooh. I don't know how to get the half-way size. So I'm just using random numbers */ static void view_three(GtkWidget *w, gpointer data) { - gtk_paned_set_position(GTK_PANED(hpane), 400); - gtk_paned_set_position(GTK_PANED(vpane), 200); + GtkAllocation alloc; + gtk_widget_get_allocation(hpane, &alloc); + gtk_paned_set_position(GTK_PANED(hpane), alloc.width/2); + gtk_widget_get_allocation(vpane, &alloc); + gtk_paned_set_position(GTK_PANED(vpane), alloc.height/2); } static GtkActionEntry menu_items[] = { @@ -577,6 +628,7 @@ static GtkActionEntry menu_items[] = { { "SaveFile", GTK_STOCK_SAVE, NULL, CTRLCHAR "S", NULL, G_CALLBACK(file_save) }, { "Print", GTK_STOCK_PRINT, NULL, CTRLCHAR "P", NULL, G_CALLBACK(do_print) }, { "Import", NULL, "Import", NULL, NULL, G_CALLBACK(import_dialog) }, + { "AddDive", NULL, "Add Dive", NULL, NULL, G_CALLBACK(add_dive_cb) }, { "Preferences", NULL, "Preferences", PREFERENCE_ACCEL, NULL, G_CALLBACK(preferences_dialog) }, { "Renumber", NULL, "Renumber", NULL, NULL, G_CALLBACK(renumber_dialog) }, { "SelectEvents", NULL, "SelectEvents", NULL, NULL, G_CALLBACK(selectevents_dialog) }, @@ -597,13 +649,14 @@ static const gchar* ui_string = " \ \ \ \ - \ - \ \ - \ + \ \ \ \ + \ + \ + \ \ \ \ @@ -646,10 +699,8 @@ void init_ui(int *argcp, char ***argvp) { GtkWidget *win; GtkWidget *notebook; - GtkWidget *dive_info; + GtkWidget *nb_page; GtkWidget *dive_list; - GtkWidget *equipment; - GtkWidget *stats; GtkWidget *menubar; GtkWidget *vbox; GdkScreen *screen; @@ -672,6 +723,8 @@ void init_ui(int *argcp, char ***argvp) output_units.volume = CUFT; if (subsurface_get_conf("fahrenheit", PREF_BOOL)) output_units.temperature = FAHRENHEIT; + if (subsurface_get_conf("lbs", PREF_BOOL)) + output_units.weight = LBS; /* an unset key is FALSE - all these are hidden by default */ visible_cols.cylinder = PTR_TO_BOOL(subsurface_get_conf("CYLINDER", PREF_BOOL)); visible_cols.temperature = PTR_TO_BOOL(subsurface_get_conf("TEMPERATURE", PREF_BOOL)); @@ -681,6 +734,10 @@ void init_ui(int *argcp, char ***argvp) divelist_font = subsurface_get_conf("divelist_font", PREF_STRING); + default_dive_computer_vendor = subsurface_get_conf("dive_computer_vendor", PREF_STRING); + default_dive_computer_product = subsurface_get_conf("dive_computer_product", PREF_STRING); + default_dive_computer_device = subsurface_get_conf("dive_computer_device", PREF_STRING); + error_info_bar = NULL; win = gtk_window_new(GTK_WINDOW_TOPLEVEL); g_set_application_name ("subsurface"); @@ -735,16 +792,20 @@ void init_ui(int *argcp, char ***argvp) gtk_paned_add2(GTK_PANED(hpane), 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("Dive Notes")); + nb_page = extended_dive_info_widget(); + gtk_notebook_append_page(GTK_NOTEBOOK(notebook), nb_page, gtk_label_new("Dive Notes")); /* Frame for dive equipment */ - equipment = equipment_widget(); - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), equipment, gtk_label_new("Equipment")); + nb_page = equipment_widget(); + gtk_notebook_append_page(GTK_NOTEBOOK(notebook), nb_page, gtk_label_new("Equipment")); + + /* Frame for single dive statistics */ + nb_page = single_stats_widget(); + gtk_notebook_append_page(GTK_NOTEBOOK(notebook), nb_page, gtk_label_new("Dive Info")); - /* Frame for dive statistics */ - stats = stats_widget(); - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), stats, gtk_label_new("Info & Stats")); + /* Frame for total dive statistics */ + nb_page = total_stats_widget(); + gtk_notebook_append_page(GTK_NOTEBOOK(notebook), nb_page, gtk_label_new("Stats")); gtk_widget_set_app_paintable(win, TRUE); gtk_widget_show_all(win); @@ -757,6 +818,11 @@ void run_ui(void) gtk_main(); } +void exit_ui(void) +{ + subsurface_close_conf(); +} + typedef struct { cairo_rectangle_int_t rect; const char *text; @@ -855,32 +921,61 @@ int process_ui_events(void) return ret; } - -static void fill_computer_list(GtkListStore *store) +static int fill_computer_list(GtkListStore *store) { + int index = -1, i; GtkTreeIter iter; - struct device_list *list = device_list; + dc_iterator_t *iterator = NULL; + dc_descriptor_t *descriptor = NULL; + + i = 0; + dc_descriptor_iterator(&iterator); + while (dc_iterator_next (iterator, &descriptor) == DC_STATUS_SUCCESS) { + const char *vendor = dc_descriptor_get_vendor(descriptor); + const char *product = dc_descriptor_get_product(descriptor); - for (list = device_list ; list->name ; list++) { gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, - 0, list->name, - 1, list->type, + 0, descriptor, -1); + if (is_default_dive_computer(vendor, product)) + index = i; + i++; } + dc_iterator_free(iterator); + return index; } +void render_dive_computer(GtkCellLayout *cell, + GtkCellRenderer *renderer, + GtkTreeModel *model, + GtkTreeIter *iter, + gpointer data) +{ + char buffer[40]; + dc_descriptor_t *descriptor = NULL; + const char *vendor, *product; + + gtk_tree_model_get(model, iter, 0, &descriptor, -1); + vendor = dc_descriptor_get_vendor(descriptor); + product = dc_descriptor_get_product(descriptor); + snprintf(buffer, sizeof(buffer), "%s %s", vendor, product); + g_object_set(renderer, "text", buffer, NULL); +} + + static GtkComboBox *dive_computer_selector(GtkWidget *vbox) { GtkWidget *hbox, *combo_box, *frame; GtkListStore *model; GtkCellRenderer *renderer; + int default_index; hbox = gtk_hbox_new(FALSE, 6); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 3); - model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT); - fill_computer_list(model); + model = gtk_list_store_new(1, G_TYPE_POINTER); + default_index = fill_computer_list(model); frame = gtk_frame_new("Dive computer"); gtk_box_pack_start(GTK_BOX(hbox), frame, FALSE, TRUE, 3); @@ -890,11 +985,21 @@ static GtkComboBox *dive_computer_selector(GtkWidget *vbox) renderer = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo_box), renderer, TRUE); - gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo_box), renderer, "text", 0, NULL); + gtk_cell_layout_set_cell_data_func(GTK_CELL_LAYOUT(combo_box), renderer, render_dive_computer, NULL, NULL); + + gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), default_index); return GTK_COMBO_BOX(combo_box); } +const char *subsurface_device_name() +{ + if (!default_dive_computer_device || !*default_dive_computer_device) + return subsurface_USB_name(); + else + return default_dive_computer_device; +} + static GtkEntry *dive_computer_device(GtkWidget *vbox) { GtkWidget *hbox, *entry, *frame; @@ -907,7 +1012,7 @@ static GtkEntry *dive_computer_device(GtkWidget *vbox) entry = gtk_entry_new(); gtk_container_add(GTK_CONTAINER(frame), entry); - gtk_entry_set_text(GTK_ENTRY(entry), subsurface_USB_name()); + gtk_entry_set_text(GTK_ENTRY(entry), subsurface_device_name()); return GTK_ENTRY(entry); } @@ -959,7 +1064,7 @@ static GtkWidget *xml_file_selector(GtkWidget *vbox, GtkWidget *main_dialog) static void do_import_file(gpointer data, gpointer user_data) { GError *error = NULL; - parse_xml_file(data, &error); + parse_file(data, &error); if (error != NULL) { @@ -969,10 +1074,33 @@ static void do_import_file(gpointer data, gpointer user_data) } } +static GtkWidget *import_dive_computer(device_data_t *data, GtkDialog *dialog) +{ + GError *error; + GtkWidget *vbox, *info, *container, *label, *button; + + error = do_import(data); + if (!error) + return NULL; + + button = gtk_dialog_get_widget_for_response(dialog, GTK_RESPONSE_ACCEPT); + gtk_button_set_use_stock(GTK_BUTTON(button), 0); + gtk_button_set_label(GTK_BUTTON(button), "Retry"); + + vbox = gtk_dialog_get_content_area(dialog); + + info = gtk_info_bar_new(); + container = gtk_info_bar_get_content_area(GTK_INFO_BAR(info)); + label = gtk_label_new(error->message); + gtk_container_add(GTK_CONTAINER(container), label); + gtk_box_pack_start(GTK_BOX(vbox), info, FALSE, FALSE, 0); + return info; +} + void import_dialog(GtkWidget *w, gpointer data) { int result; - GtkWidget *dialog, *hbox, *vbox, *label; + GtkWidget *dialog, *hbox, *vbox, *label, *info = NULL; GtkComboBox *computer; GtkEntry *device; GtkWidget *XMLchooser; @@ -998,30 +1126,42 @@ void import_dialog(GtkWidget *w, gpointer data) devicedata.progress.bar = gtk_progress_bar_new(); gtk_container_add(GTK_CONTAINER(hbox), devicedata.progress.bar); +repeat: gtk_widget_show_all(dialog); result = gtk_dialog_run(GTK_DIALOG(dialog)); switch (result) { - int type; + dc_descriptor_t *descriptor; GtkTreeIter iter; GtkTreeModel *model; - const char *comp; GSList *list; case GTK_RESPONSE_ACCEPT: /* what happened - did the user pick a file? In that case * we ignore whether a dive computer model was picked */ + if (info) + gtk_widget_destroy(info); list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(XMLchooser)); if (g_slist_length(list) == 0) { + const char *vendor, *product; + if (!gtk_combo_box_get_active_iter(computer, &iter)) break; model = gtk_combo_box_get_model(computer); gtk_tree_model_get(model, &iter, - 0, &comp, - 1, &type, + 0, &descriptor, -1); - devicedata.type = type; - devicedata.name = comp; + + vendor = dc_descriptor_get_vendor(descriptor); + product = dc_descriptor_get_product(descriptor); + + devicedata.descriptor = descriptor; + devicedata.vendor = vendor; + devicedata.product = product; devicedata.devname = gtk_entry_get_text(device); - do_import(&devicedata); + set_default_dive_computer(vendor, product); + set_default_dive_computer_device(devicedata.devname); + info = import_dive_computer(&devicedata, GTK_DIALOG(dialog)); + if (info) + goto repeat; } else { g_slist_foreach(list,do_import_file,NULL); g_slist_free(list); @@ -1040,6 +1180,10 @@ void update_progressbar(progressbar_t *progress, double value) gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress->bar), value); } +void update_progressbar_text(progressbar_t *progress, const char *text) +{ + gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress->bar), text); +} void set_filename(const char *filename) {