summaryrefslogtreecommitdiffstats
path: root/dive.c
diff options
context:
space:
mode:
Diffstat (limited to 'dive.c')
-rw-r--r--dive.c160
1 files changed, 159 insertions, 1 deletions
diff --git a/dive.c b/dive.c
index a98b10412..d2cda168d 100644
--- a/dive.c
+++ b/dive.c
@@ -6,6 +6,8 @@
#include "gettext.h"
#include "dive.h"
+struct tag_entry *g_tag_list = NULL;
+
void add_event(struct divecomputer *dc, int time, int type, int flags, int value, const char *name)
{
struct event *ev, **p;
@@ -189,6 +191,7 @@ struct dive *alloc_dive(void)
if (!dive)
exit(1);
memset(dive, 0, sizeof(*dive));
+ taglist_init(&(dive->tag_list));
return dive;
}
@@ -1813,6 +1816,161 @@ static void join_dive_computers(struct divecomputer *res, struct divecomputer *a
remove_redundant_dc(res, prefer_downloaded);
}
+int taglist_get_tagstring(struct tag_entry *tag_list, char *buffer, int len) {
+ int i = 0;
+ struct tag_entry *tmp;
+ tmp = tag_list->next;
+ memset(buffer, 0, len);
+ while(tmp != NULL) {
+ int newlength = strlen(tmp->tag->name);
+ if (i > 0)
+ newlength += 2;
+ if ((i+newlength) < len) {
+ if (i > 0) {
+ strcpy(buffer+i, ", ");
+ strcpy(buffer+i+2, tmp->tag->name);
+ } else {
+ strcpy(buffer, tmp->tag->name);
+ }
+ } else {
+ return i;
+ }
+ i += newlength;
+ tmp = tmp->next;
+ }
+ return i;
+}
+
+struct divetag *taglist_get_tag(struct tag_entry *tag_list, const char *tag)
+{
+ struct tag_entry *tmp;
+ tmp = tag_list->next;
+ while(tmp != NULL) {
+ if (tmp->tag != NULL)
+ if (strcmp(tmp->tag->name, tag) == 0)
+ return tmp->tag;
+ else
+ tmp = tmp->next;
+ }
+ return NULL;
+}
+
+static inline void taglist_free_divetag(struct divetag *tag) {
+ if (tag->name != NULL)
+ free(tag->name);
+ if (tag->source != NULL)
+ free(tag->source);
+ free(tag);
+}
+
+/* Add a tag to the tag_list, keep the list sorted */
+static struct divetag *taglist_add_divetag(struct tag_entry *tag_list, struct divetag *tag)
+{
+ struct tag_entry *tmp, *last;
+ last = tag_list;
+ tmp = tag_list->next;
+ while(1) {
+ if (tmp == NULL || strcmp(tmp->tag->name, tag->name) > 0) {
+ /* Insert in front of it */
+ last->next = malloc(sizeof(struct tag_entry));
+ last->next->next = tmp;
+ last->next->tag = tag;
+ return last->next->tag;
+ } else if (strcmp(tmp->tag->name, tag->name) == 0) {
+ /* Already in list */
+ return tmp->tag;
+ } else {
+ last = tmp;
+ tmp = tmp->next;
+ }
+ }
+}
+
+struct divetag *taglist_add_tag(struct tag_entry *tag_list, const char *tag)
+{
+ struct divetag *ret_tag, *new_tag;
+ const char *translation;
+ new_tag = malloc(sizeof(struct divetag));
+
+ translation = translate("gettextFromC", tag);
+ if (strcmp(tag, translation) == 0) {
+ new_tag->source = NULL;
+ new_tag->name = malloc(strlen(tag)+1);
+ memcpy(new_tag->name, tag, strlen(tag)+1);
+ } else {
+ new_tag->name = malloc(strlen(translation)+1);
+ memcpy(new_tag->name, translation, strlen(translation)+1);
+ new_tag->source = malloc(strlen(tag)+1);
+ memcpy(new_tag->source, tag, strlen(tag)+1);
+ }
+ /* Try to insert new_tag into g_tag_list if we are not operating on it */
+ if (tag_list != g_tag_list) {
+ ret_tag = taglist_add_divetag(g_tag_list, new_tag);
+ /* g_tag_list already contains new_tag, free the duplicate */
+ if (ret_tag != new_tag)
+ taglist_free_divetag(new_tag);
+ ret_tag = taglist_add_divetag(tag_list, ret_tag);
+ } else {
+ ret_tag = taglist_add_divetag(tag_list, new_tag);
+ if (ret_tag != new_tag)
+ taglist_free_divetag(new_tag);
+ }
+ return ret_tag;
+}
+
+void taglist_init(struct tag_entry **tag_list) {
+ *tag_list = malloc(sizeof(struct tag_entry));
+ (*tag_list)->next = NULL;
+ (*tag_list)->tag = NULL;
+}
+
+/* Clear everything but the first element */
+void taglist_clear(struct tag_entry *tag_list) {
+ struct tag_entry *current_tag_entry, *next;
+ current_tag_entry = tag_list->next;
+ while (current_tag_entry != NULL) {
+ next = current_tag_entry->next;
+ free(current_tag_entry);
+ current_tag_entry = next;
+ }
+ tag_list->next = NULL;
+}
+
+/* Merge src1 and src2, write to *dst */
+static void taglist_merge(struct tag_entry *dst, struct tag_entry *src1, struct tag_entry *src2)
+{
+ struct tag_entry *current_tag_entry;
+ current_tag_entry = src1->next;
+ while (current_tag_entry != NULL) {
+ taglist_add_divetag(dst, current_tag_entry->tag);
+ current_tag_entry = current_tag_entry->next;
+ }
+ current_tag_entry = src2->next;
+ while (current_tag_entry != NULL) {
+ taglist_add_divetag(dst, current_tag_entry->tag);
+ current_tag_entry = current_tag_entry->next;
+ }
+}
+
+void taglist_init_global()
+{
+ int i;
+ const char* default_tags[] = {
+ QT_TRANSLATE_NOOP("gettextFromC", "boat"), QT_TRANSLATE_NOOP("gettextFromC", "shore"), QT_TRANSLATE_NOOP("gettextFromC", "drift"),
+ QT_TRANSLATE_NOOP("gettextFromC", "deep"), QT_TRANSLATE_NOOP("gettextFromC", "cavern") , QT_TRANSLATE_NOOP("gettextFromC", "ice"),
+ QT_TRANSLATE_NOOP("gettextFromC", "wreck"), QT_TRANSLATE_NOOP("gettextFromC", "cave"), QT_TRANSLATE_NOOP("gettextFromC", "altitude"),
+ QT_TRANSLATE_NOOP("gettextFromC", "pool"), QT_TRANSLATE_NOOP("gettextFromC", "lake"), QT_TRANSLATE_NOOP("gettextFromC", "river"),
+ QT_TRANSLATE_NOOP("gettextFromC", "night"), QT_TRANSLATE_NOOP("gettextFromC", "fresh"), QT_TRANSLATE_NOOP("gettextFromC", "student"),
+ QT_TRANSLATE_NOOP("gettextFromC", "instructor"), QT_TRANSLATE_NOOP("gettextFromC", "photo"), QT_TRANSLATE_NOOP("gettextFromC", "video"),
+ QT_TRANSLATE_NOOP("gettextFromC", "deco")
+ };
+
+ taglist_init(&g_tag_list);
+
+ for(i=0; i<sizeof(default_tags)/sizeof(char*); i++)
+ taglist_add_tag(g_tag_list, default_tags[i]);
+}
+
struct dive *merge_dives(struct dive *a, struct dive *b, int offset, bool prefer_downloaded)
{
struct dive *res = alloc_dive();
@@ -1841,7 +1999,7 @@ struct dive *merge_dives(struct dive *a, struct dive *b, int offset, bool prefer
MERGE_MAX(res, a, b, number);
MERGE_NONZERO(res, a, b, cns);
MERGE_NONZERO(res, a, b, visibility);
- MERGE_NONZERO(res, a, b, dive_tags);
+ taglist_merge(res->tag_list, a->tag_list, b->tag_list);
merge_equipment(res, a, b);
merge_airtemps(res, a, b);
if (dl) {