X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=gtk-gui.c;h=4ac538a062bdbe32f72ca71d1401e6446e4ecea2;hb=4c6f142e85969708983e2ffd7d413e01ac84b176;hp=ee3ad2ef11583109f80254007757833970e34fe5;hpb=9d469862af57227c93da6f2a253b76677711c886;p=ext%2Fsubsurface.git diff --git a/gtk-gui.c b/gtk-gui.c index ee3ad2e..4ac538a 100644 --- a/gtk-gui.c +++ b/gtk-gui.c @@ -116,7 +116,7 @@ static void file_open(GtkWidget *w, gpointer data) GError *error = NULL; while(filenames != NULL) { - filename = (char *)filenames->data; + filename = filenames->data; parse_xml_file(filename, &error); if (error != NULL) { @@ -129,8 +129,7 @@ static void file_open(GtkWidget *w, gpointer data) filenames = g_slist_next(filenames); } g_slist_free(filenames); - report_dives(); - dive_list_update_dives(); + report_dives(FALSE); } gtk_widget_destroy(dialog); } @@ -389,6 +388,7 @@ static void preferences_dialog(GtkWidget *w, gpointer data) static void renumber_dialog(GtkWidget *w, gpointer data) { int result; + struct dive *dive; GtkWidget *dialog, *frame, *button, *vbox; dialog = gtk_dialog_new_with_buttons("Renumber", @@ -406,6 +406,14 @@ static void renumber_dialog(GtkWidget *w, gpointer data) button = gtk_spin_button_new_with_range(1, 50000, 1); gtk_container_add(GTK_CONTAINER(frame), button); + /* + * Do we have a number for the first dive already? Use that + * as the default. + */ + dive = get_dive(0); + if (dive && dive->number) + gtk_spin_button_set_value(GTK_SPIN_BUTTON(button), dive->number); + gtk_widget_show_all(dialog); result = gtk_dialog_run(GTK_DIALOG(dialog)); if (result == GTK_RESPONSE_ACCEPT) { @@ -588,11 +596,14 @@ void init_ui(int argc, char **argv) GtkWidget *equipment; GtkWidget *menubar; GtkWidget *vbox; + GtkSettings *settings; static const GtkTargetEntry notebook_target = { "GTK_NOTEBOOK_TAB", GTK_TARGET_SAME_APP, 0 }; gtk_init(&argc, &argv); + settings = gtk_settings_get_default(); + gtk_settings_set_long_property(settings, "gtk_tooltip_timeout", 10, "subsurface setting"); g_type_init(); gconf = gconf_client_get_default(); @@ -670,22 +681,75 @@ void run_ui(void) gtk_main(); } +typedef struct { + cairo_rectangle_int_t rect; + const char *text; +} tooltip_record_t; + +static tooltip_record_t *tooltip_rects; +static int tooltips; + +void attach_tooltip(int x, int y, int w, int h, const char *text) +{ + cairo_rectangle_int_t *rect; + tooltip_rects = realloc(tooltip_rects, (tooltips + 1) * sizeof(tooltip_record_t)); + rect = &tooltip_rects[tooltips].rect; + rect->x = x; + rect->y = y; + rect->width = w; + rect->height = h; + tooltip_rects[tooltips].text = text; + tooltips++; +} + +#define INSIDE_RECT(_r,_x,_y) ((_r.x <= _x) && (_r.x + _r.width >= _x) && \ + (_r.y <= _y) && (_r.y + _r.height >= _y)) + +static gboolean profile_tooltip (GtkWidget *widget, gint x, gint y, + gboolean keyboard_mode, GtkTooltip *tooltip, gpointer user_data) +{ + int i; + cairo_rectangle_int_t *drawing_area = user_data; + gint tx = x - drawing_area->x; /* get transformed coordinates */ + gint ty = y - drawing_area->y; + + /* are we over an event marker ? */ + for (i = 0; i < tooltips; i++) { + if (INSIDE_RECT(tooltip_rects[i].rect, tx, ty)) { + gtk_tooltip_set_text(tooltip,tooltip_rects[i].text); + return TRUE; /* show tooltip */ + } + } + return FALSE; /* don't show tooltip */ +} + static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data) { struct dive *dive = current_dive; struct graphics_context gc = { .printer = 0 }; - int w,h; + static cairo_rectangle_int_t drawing_area; - w = widget->allocation.width; - h = widget->allocation.height; + /* the drawing area gives TOTAL width * height - x,y is used as the topx/topy offset + * so effective drawing area is width-2x * height-2y */ + drawing_area.width = widget->allocation.width; + drawing_area.height = widget->allocation.height; + drawing_area.x = drawing_area.width / 20.0; + drawing_area.y = drawing_area.height / 20.0; gc.cr = gdk_cairo_create(widget->window); + g_object_set(widget, "has-tooltip", TRUE, NULL); + g_signal_connect(widget, "query-tooltip", G_CALLBACK(profile_tooltip), &drawing_area); set_source_rgb(&gc, 0, 0, 0); cairo_paint(gc.cr); - if (dive) - plot(&gc, w, h, dive); - + if (dive) { + if (tooltip_rects) { + free(tooltip_rects); + tooltip_rects = NULL; + } + tooltips = 0; + plot(&gc, &drawing_area, dive); + } cairo_destroy(gc.cr); return FALSE; @@ -772,12 +836,70 @@ static GtkEntry *dive_computer_device(GtkWidget *vbox) return GTK_ENTRY(entry); } +/* once a file is selected in the FileChooserButton we want to exit the import dialog */ +static void on_file_set(GtkFileChooserButton *widget, gpointer _data) +{ + GtkDialog *main_dialog = _data; + + gtk_dialog_response(main_dialog, GTK_RESPONSE_ACCEPT); +} + +static GtkWidget *xml_file_selector(GtkWidget *vbox, GtkWidget *main_dialog) +{ + GtkWidget *hbox, *frame, *chooser, *dialog; + GtkFileFilter *filter; + + hbox = gtk_hbox_new(FALSE, 6); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 3); + + frame = gtk_frame_new("XML file name"); + gtk_box_pack_start(GTK_BOX(hbox), frame, FALSE, TRUE, 3); + dialog = gtk_file_chooser_dialog_new("Open XML 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), FALSE); + + filter = gtk_file_filter_new(); + gtk_file_filter_add_pattern(filter, "*.xml"); + gtk_file_filter_add_pattern(filter, "*.XML"); + gtk_file_filter_add_pattern(filter, "*.sda"); + gtk_file_filter_add_pattern(filter, "*.SDA"); + gtk_file_filter_add_mime_type(filter, "text/xml"); + gtk_file_filter_set_name(filter, "XML file"); + gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter); + + chooser = gtk_file_chooser_button_new_with_dialog(dialog); + g_signal_connect(G_OBJECT(chooser), "file-set", G_CALLBACK(on_file_set), main_dialog); + + gtk_file_chooser_button_set_width_chars(GTK_FILE_CHOOSER_BUTTON(chooser), 30); + gtk_container_add(GTK_CONTAINER(frame), chooser); + + return chooser; +} + +static void do_import_file(gpointer data, gpointer user_data) +{ + GError *error = NULL; + parse_xml_file(data, &error); + + if (error != NULL) + { + report_error(error); + g_error_free(error); + error = NULL; + } +} + void import_dialog(GtkWidget *w, gpointer data) { int result; - GtkWidget *dialog, *hbox, *vbox; + GtkWidget *dialog, *hbox, *vbox, *label; GtkComboBox *computer; GtkEntry *device; + GtkWidget *XMLchooser; device_data_t devicedata = { .devname = NULL, }; @@ -790,10 +912,11 @@ void import_dialog(GtkWidget *w, gpointer data) NULL); vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); - + label = gtk_label_new("Import: \nLoad XML file or import directly from dive computer"); + gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 3); + XMLchooser = xml_file_selector(vbox, dialog); computer = dive_computer_selector(vbox); device = dive_computer_device(vbox); - hbox = gtk_hbox_new(FALSE, 6); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 3); devicedata.progress.bar = gtk_progress_bar_new(); @@ -806,26 +929,34 @@ void import_dialog(GtkWidget *w, gpointer data) GtkTreeIter iter; GtkTreeModel *model; const char *comp; + GSList *list; case GTK_RESPONSE_ACCEPT: - 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, - -1); - devicedata.type = type; - devicedata.name = comp; - devicedata.devname = gtk_entry_get_text(device); - do_import(&devicedata); + /* what happened - did the user pick a file? In that case + * we ignore whether a dive computer model was picked */ + list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(XMLchooser)); + if (g_slist_length(list) == 0) { + 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, + -1); + devicedata.type = type; + devicedata.name = comp; + devicedata.devname = gtk_entry_get_text(device); + do_import(&devicedata); + } else { + g_slist_foreach(list,do_import_file,NULL); + g_slist_free(list); + } break; default: break; } gtk_widget_destroy(dialog); - report_dives(); - dive_list_update_dives(); + report_dives(TRUE); } void update_progressbar(progressbar_t *progress, double value)