summaryrefslogtreecommitdiffstats
path: root/divelist-gtk.c
diff options
context:
space:
mode:
Diffstat (limited to 'divelist-gtk.c')
-rw-r--r--divelist-gtk.c169
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);
/*