diff options
Diffstat (limited to 'divelist-gtk.c')
-rw-r--r-- | divelist-gtk.c | 169 |
1 files changed, 135 insertions, 34 deletions
diff --git a/divelist-gtk.c b/divelist-gtk.c index fc90cdf26..79613e012 100644 --- a/divelist-gtk.c +++ b/divelist-gtk.c @@ -26,12 +26,8 @@ #include <math.h> #include <glib/gi18n.h> #include <assert.h> -#ifdef LIBZIP #include <zip.h> -#endif -#ifdef XSLT #include <libxslt/transform.h> -#endif #include "dive.h" #include "divelist.h" @@ -59,6 +55,7 @@ static struct DiveList dive_list; #define TREESTORE(_dl) GTK_TREE_STORE((_dl).treemodel) #define LISTSTORE(_dl) GTK_TREE_STORE((_dl).listmodel) +static gboolean ignore_selection_changes = FALSE; static gboolean in_set_cursor = FALSE; static gboolean set_selected(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data); @@ -675,7 +672,11 @@ static void fill_dive_list(void) i = dive_table.nr; while (--i >= 0) { struct dive *dive = get_dive(i); - dive_trip_t *trip = dive->divetrip; + dive_trip_t *trip; + if (((dive->dive_tags & DTAG_INVALID) && !prefs.display_invalid_dives) || + (dive->dive_tags & dive_mask) != dive_mask) + continue; + trip = dive->divetrip; if (!trip) { parent_ptr = NULL; @@ -761,8 +762,10 @@ static void restore_tree_state(void); void dive_list_update_dives(void) { dive_table.preexisting = dive_table.nr; + ignore_selection_changes = TRUE; gtk_tree_store_clear(TREESTORE(dive_list)); gtk_tree_store_clear(LISTSTORE(dive_list)); + ignore_selection_changes = FALSE; fill_dive_list(); restore_tree_state(); repaint_dive(); @@ -967,16 +970,13 @@ static void edit_dive_when_cb(GtkWidget *menuitem, struct dive *dive) } } -#if HAVE_OSM_GPS_MAP static void show_gps_location_cb(GtkWidget *menuitem, struct dive *dive) { show_gps_location(dive, NULL); } -#endif gboolean icon_click_cb(GtkWidget *w, GdkEventButton *event, gpointer data) { -#if HAVE_OSM_GPS_MAP GtkTreePath *path = NULL; GtkTreeIter iter; GtkTreeViewColumn *col; @@ -997,7 +997,6 @@ gboolean icon_click_cb(GtkWidget *w, GdkEventButton *event, gpointer data) if (path) gtk_tree_path_free(path); } -#endif /* keep processing the click */ return FALSE; } @@ -1026,6 +1025,47 @@ static void save_as_cb(GtkWidget *menuitem, struct dive *dive) } } +static void invalid_dives_cb(GtkWidget *menuitem, GtkTreePath *path) +{ + int i; + int changed = 0; + struct dive *dive; + + if (!amount_selected) + return; + /* walk the dive list in chronological order */ + for_each_dive(i, dive) { + if (!dive->selected) + continue; + /* now swap the invalid tag if just 1 dive was selected + * otherwise set all to invalid */ + if(amount_selected == 1) { + if (dive->dive_tags & DTAG_INVALID) + dive->dive_tags &= ~DTAG_INVALID; + else + dive->dive_tags |= DTAG_INVALID; + changed = 1; + } else { + if (! dive->dive_tags & DTAG_INVALID) { + dive->dive_tags |= DTAG_INVALID; + changed = 1; + } + } + /* if invalid dives aren't shown they need to be + * de-selected here to avoid confusion */ + if (dive->selected && !prefs.display_invalid_dives) { + dive->selected = 0; + amount_selected--; + } + } + if (amount_selected == 0) + selected_dive = -1; + if (changed) { + dive_list_update_dives(); + mark_divelist_changed(TRUE); + } +} + static void expand_all_cb(GtkWidget *menuitem, GtkTreeView *tree_view) { gtk_tree_view_expand_all(tree_view); @@ -1307,8 +1347,31 @@ static void delete_dive_cb(GtkWidget *menuitem, GtkTreePath *path) mark_divelist_changed(TRUE); } -#if defined(LIBZIP) && defined(XSLT) -static void export_selected_dives_cb(GtkWidget *menuitem, GtkTreePath *path) +void divelogs_status_dialog(char *error, GtkMessageType type) +{ + GtkWidget *dialog, *vbox, *label; + + dialog = gtk_message_dialog_new( + GTK_WINDOW(main_window), + GTK_DIALOG_DESTROY_WITH_PARENT, + type, + GTK_BUTTONS_OK, + _("%s: Response from divelogs.de"), type == GTK_MESSAGE_INFO ? _("Info") : _("Error") + ); + + vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); + + label = create_label("%s", error); + gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); + + gtk_widget_show_all(dialog); + gtk_dialog_run(GTK_DIALOG(dialog)); + + gtk_widget_destroy(dialog); + +} + +static void upload_dives_divelogs(const gboolean selected) { int i; struct dive *dive; @@ -1322,6 +1385,9 @@ static void export_selected_dives_cb(GtkWidget *menuitem, GtkTreePath *path) struct zip_source *s[dive_table.nr]; struct zip *zip; const gchar *tmpdir = g_get_tmp_dir(); + GtkMessageType type; + char *error = NULL; + char *parsed = NULL, *endat = NULL; /* * Creating a temporary .DLD file to be eventually uploaded to @@ -1345,7 +1411,7 @@ static void export_selected_dives_cb(GtkWidget *menuitem, GtkTreePath *path) dive = get_dive(i); if (!dive) continue; - if (!dive->selected) + if (selected && !dive->selected) continue; f = tmpfile(); @@ -1392,15 +1458,47 @@ static void export_selected_dives_cb(GtkWidget *menuitem, GtkTreePath *path) } } zip_close(zip); - if (divelogde_upload(tempfile)) - g_unlink(tempfile); - else - fprintf(stderr,"upload of %s failed\n", tempfile); + if (!divelogde_upload(tempfile, &error)) { + type = GTK_MESSAGE_ERROR; + } else { + /* The upload status XML message should be parsed + * properly and displayed in a sensible manner. But just + * displaying the information part of the raw message is + * better than nothing. + * And at least the dialog is customized to indicate + * error or success. + */ + if (error) { + parsed = strstr(error, "<Login>"); + endat = strstr(error, "</divelogsDataImport>"); + if (parsed && endat) + *endat = '\0'; + } + if (error && strstr(error, "failed")) + type = GTK_MESSAGE_ERROR; + else + type = GTK_MESSAGE_INFO; + } + if (parsed) + divelogs_status_dialog(parsed, type); + else if (error) + divelogs_status_dialog(error, type); + free(error); + + g_unlink(tempfile); g_free(tempfile); } -#endif -#if defined(XSLT) +void upload_selected_dives_divelogs_cb(GtkWidget *menuitem, GtkTreePath *path) +{ + upload_dives_divelogs(TRUE); +} + +void upload_all_dives_divelogs_cb() +{ + upload_dives_divelogs(FALSE); +} + static void export_dives_uddf(const gboolean selected) { FILE *f; @@ -1484,7 +1582,6 @@ void export_all_dives_uddf_cb() { export_dives_uddf(FALSE); } -#endif static void merge_dives_cb(GtkWidget *menuitem, void *unused) { @@ -1538,12 +1635,8 @@ static void popup_divelist_menu(GtkTreeView *tree_view, GtkTreeModel *model, int char deleteplurallabel[] = N_("Delete dives"); char deletesinglelabel[] = N_("Delete dive"); char *deletelabel; -#if defined(XSLT) char exportuddflabel[] = N_("Export dive(s) to UDDF"); -#endif -#if defined(LIBZIP) && defined(XSLT) - char exportlabel[] = N_("Export dive(s)"); -#endif + char uploaddivelogslabel[] = N_("Upload dive(s) to divelogs.de"); GtkTreePath *path, *prevpath, *nextpath; GtkTreeIter iter, previter, nextiter; int idx, previdx, nextidx; @@ -1591,7 +1684,7 @@ static void popup_divelist_menu(GtkTreeView *tree_view, GtkTreeModel *model, int gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); } else { dive = get_dive(idx); - /* if we right click on selected dive(s), edit or delete those */ + /* if we right click on selected dive(s), edit, delete or tag them as invalid */ if (dive->selected) { if (amount_selected == 1) { deletelabel = _(deletesinglelabel); @@ -1607,21 +1700,28 @@ static void popup_divelist_menu(GtkTreeView *tree_view, GtkTreeModel *model, int g_signal_connect(menuitem, "activate", G_CALLBACK(save_as_cb), dive); gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + if (amount_selected == 1) { + if (dive->dive_tags & DTAG_INVALID) + menuitem = gtk_menu_item_new_with_label(_("Mark valid")); + else + menuitem = gtk_menu_item_new_with_label(_("Mark invalid")); + } else { + menuitem = gtk_menu_item_new_with_label(_("Mark invalid")); + } + g_signal_connect(menuitem, "activate", G_CALLBACK(invalid_dives_cb), path); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + menuitem = gtk_menu_item_new_with_label(deletelabel); g_signal_connect(menuitem, "activate", G_CALLBACK(delete_selected_dives_cb), path); gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); -#if defined(LIBZIP) && defined(XSLT) - menuitem = gtk_menu_item_new_with_label(exportlabel); - g_signal_connect(menuitem, "activate", G_CALLBACK(export_selected_dives_cb), path); + menuitem = gtk_menu_item_new_with_label(_(uploaddivelogslabel)); + g_signal_connect(menuitem, "activate", G_CALLBACK(upload_selected_dives_divelogs_cb), path); gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); -#endif -#if defined(XSLT) - menuitem = gtk_menu_item_new_with_label(exportuddflabel); + menuitem = gtk_menu_item_new_with_label(_(exportuddflabel)); g_signal_connect(menuitem, "activate", G_CALLBACK(export_selected_dives_uddf_cb), path); gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); -#endif menuitem = gtk_menu_item_new_with_label(editlabel); g_signal_connect(menuitem, "activate", G_CALLBACK(edit_selected_dives_cb), NULL); @@ -1645,14 +1745,12 @@ static void popup_divelist_menu(GtkTreeView *tree_view, GtkTreeModel *model, int g_signal_connect(menuitem, "activate", G_CALLBACK(edit_dive_from_path_cb), path); gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); } -#if HAVE_OSM_GPS_MAP /* Only offer to show on map if it has a location. */ if (dive_has_gps_location(dive)) { menuitem = gtk_menu_item_new_with_label(_("Show in map")); g_signal_connect(menuitem, "activate", G_CALLBACK(show_gps_location_cb), dive); gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); } -#endif /* only offer trip editing options when we are displaying the tree model */ if (dive_list.model == dive_list.treemodel) { int depth = gtk_tree_path_get_depth(path); @@ -1947,6 +2045,9 @@ static void selection_cb(GtkTreeSelection *selection, GtkTreeModel *model) int i, fixup; struct dive *dive; + if (ignore_selection_changes) + return; + gtk_tree_selection_selected_foreach(selection, entry_selected, model); /* |