[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: QSL labels, anyone?



Hello,

Multi-record per label is possible with gLabels and the attached
patch against latest xlog. The patch brings two optional features
for TSV export (in menu Parmaters|Dialog and windows|Export):

 1) sort by DXCC
 2) Group by callsign

The first one shockingly does what it says. For people who care about
their QSL managers and buro :-)

The second one imply the first one, and put on the same line up to
a certain number of rows having the same callsign. Then, taking the 
advantage of gLabels (see attached picture) of not complaining about
inexistant extra fields, we get multi-records.

This patch has been tested with the QSLing of a LXpedition we had
this summer on IOTA EU-157. Cheer up, cards are coming!

73
-- 
Stephane - F8CFE

Attachment: glabels_multi_records.png
Description: PNG image

Index: src/cfg.c
===================================================================
RCS file: /sources/xlog/xlog/src/cfg.c,v
retrieving revision 1.5
diff -u -p -r1.5 cfg.c
--- src/cfg.c	28 Aug 2008 07:50:44 -0000	1.5
+++ src/cfg.c	24 Nov 2008 21:00:49 -0000
@@ -176,6 +176,8 @@ config_create (void)
 	preferences.backup = 1;
 	preferences.fcc = 0;
 	preferences.tsvcalc = 0;
+	preferences.tsvsortbydxcc = 0;
+	preferences.tsvgroupbycallsign = 1;
 	preferences.viewscoring = 1;
 	preferences.scorex = 10;
 	preferences.scorey = 300;
@@ -644,6 +646,16 @@ static void config_load_from_keyfile (GK
 		preferences.tsvcalc = 0;
 	else
 		preferences.tsvcalc = preferences.tsvcalc - 1;
+	preferences.tsvsortbydxcc = g_key_file_get_integer (file, "saveas", "tsvsortbydxcc", NULL);
+	if (preferences.tsvsortbydxcc == 0)
+		preferences.tsvsortbydxcc = 0;
+	else
+		preferences.tsvsortbydxcc = preferences.tsvsortbydxcc - 1;
+	preferences.tsvgroupbycallsign = g_key_file_get_integer (file, "saveas", "tsvgroupbycallsign", NULL);
+	if (preferences.tsvgroupbycallsign == 0)
+		preferences.tsvgroupbycallsign = 1;
+	else
+		preferences.tsvgroupbycallsign = preferences.tsvgroupbycallsign - 1;
 }
 
 /*
@@ -772,6 +784,8 @@ savepreferences (void)
 	g_key_file_set_integer (file, "saveas", "adif", preferences.saveasadif + 1);
 	g_key_file_set_integer_list (file, "saveas", "tsvcolumns", preferences.saveastsv2, 18);
 	g_key_file_set_integer (file, "saveas", "tsvcalc", preferences.tsvcalc + 1);
+	g_key_file_set_integer (file, "saveas", "tsvsortbydxcc", preferences.tsvsortbydxcc + 1);
+	g_key_file_set_integer (file, "saveas", "tsvgroupbycallsign", preferences.tsvgroupbycallsign + 1);
 
 	gchar *buffer = g_key_file_to_data(file, NULL, NULL);
 	g_key_file_free(file);
Index: src/cfg.h
===================================================================
RCS file: /sources/xlog/xlog/src/cfg.h,v
retrieving revision 1.2
diff -u -p -r1.2 cfg.h
--- src/cfg.h	16 May 2008 07:04:06 -0000	1.2
+++ src/cfg.h	24 Nov 2008 21:00:49 -0000
@@ -85,6 +85,8 @@ typedef struct
 	gint saveasadif;
 	gint *saveastsv2;
 	gint tsvcalc;
+	gint tsvsortbydxcc;
+	gint tsvgroupbycallsign;
 	gint handlebarpos;
 	gchar *cwf1;
 	gchar *cwf2;
Index: src/gui_dialogsdialog.c
===================================================================
RCS file: /sources/xlog/xlog/src/gui_dialogsdialog.c,v
retrieving revision 1.34
diff -u -p -r1.34 gui_dialogsdialog.c
--- src/gui_dialogsdialog.c	19 May 2008 10:36:53 -0000	1.34
+++ src/gui_dialogsdialog.c	24 Nov 2008 21:00:49 -0000
@@ -55,13 +55,15 @@ on_menu_dialogs_activate(GtkMenuItem * m
 		*badif, *hsep,
 		*bu1, *bu2, *bu3, *bu4, *bu5, *bu6, *bu7, *bu8, *bu9, *bu10,
 		*bu11, *bu12, *bu13, *bu14, *bu15, *bu16, *bu17, *bu18,
-		*b4treeview, *tsvhbox, *bucalc,
+		*b4treeview, *tsvhbox, *bucalc, *busortbydxcc,
+		*groupbycallsignhbox, *groupbycallsignlabel, *groupbycallsignentry,
 		*bb1, *bb2, *bb3, *bb4, *bb5, *bb6, *bb7, *bb8, *bb9, *bb10,
 		*bb11, *bb12, *bb13, *bb14, *bb15, *bb16, *bb17, *bb18, *bb19,
 		*bb20, *bb21, *bb22, *bb23, *bb24, *bb25, *bb26, *bb27, *bb28,
 		*bb29, *vbox3, *bwac, *bwas, *bwaz, *biota, *bloc,
 		*countrytreeview, *dxcctreeview;
 	gboolean check;
+	gchar *temp;
 	GtkTreeViewColumn *column;
 	GtkTreeIter iter;
 	gint i, j, response;
@@ -176,7 +178,7 @@ on_menu_dialogs_activate(GtkMenuItem * m
 	vbox2 = gtk_vbox_new (FALSE, 0);
 	gtk_container_add (GTK_CONTAINER (frame), vbox2);
 	label = gtk_label_new
-(_("Fields to export when saving as TSV (Tab Separated Value) for glabels"));
+(_("Fields to export when saving as TSV (Tab Separated Value) for gLabels"));
 	gtk_container_add (GTK_CONTAINER (vbox2), label);
 	gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
 	hsep = gtk_hseparator_new ();
@@ -256,6 +258,27 @@ on_menu_dialogs_activate(GtkMenuItem * m
 		(GTK_TOGGLE_BUTTON (bucalc), preferences.tsvcalc);
 	gtk_box_pack_start (GTK_BOX (vbox2), bucalc, FALSE, FALSE, 0);
 
+	hsep = gtk_hseparator_new ();
+	gtk_container_add (GTK_CONTAINER (vbox2), hsep);
+	busortbydxcc = gtk_check_button_new_with_label (_("Sort by DXCC"));
+	gtk_toggle_button_set_active
+		(GTK_TOGGLE_BUTTON (busortbydxcc), preferences.tsvsortbydxcc);
+	gtk_box_pack_start (GTK_BOX (vbox2), busortbydxcc, FALSE, FALSE, 0);
+
+	hsep = gtk_hseparator_new ();
+	gtk_container_add (GTK_CONTAINER (vbox2), hsep);
+	groupbycallsignhbox = gtk_hbox_new (TRUE, 0);
+	gtk_container_add (GTK_CONTAINER (vbox2), groupbycallsignhbox);
+	groupbycallsignlabel = gtk_label_new (_("Group by call-sign"));
+	gtk_box_pack_start (GTK_BOX (groupbycallsignhbox), groupbycallsignlabel, FALSE, FALSE, 0);
+	groupbycallsignentry = gtk_entry_new ();
+	gtk_box_pack_start (GTK_BOX (groupbycallsignhbox), groupbycallsignentry, TRUE, TRUE, 2);
+	gtk_entry_set_max_length (GTK_ENTRY (groupbycallsignentry), 2);
+	gtk_entry_set_activates_default (GTK_ENTRY (groupbycallsignentry), TRUE);
+	temp = g_strdup_printf ("%d", preferences.tsvgroupbycallsign);
+	gtk_entry_set_text (GTK_ENTRY (groupbycallsignentry), temp);
+	g_free(temp);
+
 	vbox = gtk_vbox_new (FALSE, 0);
 	gtk_container_add (GTK_CONTAINER (notebook), vbox);
 	frame = gtk_frame_new (_("Bands"));
@@ -544,6 +567,15 @@ on_menu_dialogs_activate(GtkMenuItem * m
 		else
 			preferences.tsvcalc = 0;
 
+		check = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(busortbydxcc));
+		if (check)
+			preferences.tsvsortbydxcc = 1;
+		else
+			preferences.tsvsortbydxcc = 0;
+
+		temp = gtk_editable_get_chars (GTK_EDITABLE (groupbycallsignentry), 0, -1);
+		preferences.tsvgroupbycallsign = atoi(temp);
+
 		check = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(bb1));
 		preferences.scoringbands[BAND_2190] = check ? 1 : 0;
 		check = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(bb2));
Index: src/log.c
===================================================================
RCS file: /sources/xlog/xlog/src/log.c,v
retrieving revision 1.56
diff -u -p -r1.56 log.c
--- src/log.c	23 May 2008 10:30:33 -0000	1.56
+++ src/log.c	24 Nov 2008 21:00:50 -0000
@@ -43,6 +43,7 @@
 #include "log.h"
 #include "support.h"
 #include "main.h"
+#include "dxcc.h"
 
 extern GtkWidget *mainnotebook;
 extern programstatetype programstate;
@@ -416,14 +417,49 @@ childcheck (void)
 }
 #endif
 
+typedef gchar *item_t[QSO_FIELDS];
+
+static int savelog_compar_groupbycall(const void *b, const void *a)
+{
+	const gchar **item_a, **item_b;
+	item_a = (const gchar **)a;
+	item_b = (const gchar **)b;
+
+	return strcmp(item_a[CALL], item_b[CALL]);
+}
+
+
+extern GPtrArray *dxcc;
+
+static int savelog_compar_sortbydxcc(const void *b, const void *a)
+{
+	gint rescmp;
+	gchar **item_a, **item_b;
+	item_a = (gchar **)a;
+	item_b = (gchar **)b;
+
+	struct info info_a, info_b;
+	info_a = lookupcountry_by_callsign (item_a[CALL]);
+	info_b = lookupcountry_by_callsign (item_b[CALL]);
+	dxcc_data *d_a = g_ptr_array_index (dxcc, info_a.country);
+	dxcc_data *d_b = g_ptr_array_index (dxcc, info_b.country);
+
+	/* Sort by DXCC first, then group by call sign within same DXCC */
+	rescmp = strcmp(d_a->px, d_b->px);
+	if (rescmp != 0)
+		return rescmp;
+	return strcmp(item_a[CALL], item_b[CALL]);
+}
+
 /* saving of the log */
 void
 savelog (gpointer arg, gchar * logfile, gint type, gint first, gint last)
 {
 	LOGDB *lp;
-	gint i, j, pid;
+	gint i, j, pid, exported;
 	G_CONST_RETURN gchar *label;
 	gchar **item, *pathstr;
+	item_t *sorteditems;
 	gint fields[QSO_FIELDS], widths[QSO_FIELDS];
 	logtype *logw = (logtype *) arg;
 	GtkTreeViewColumn *column;
@@ -459,6 +495,7 @@ savelog (gpointer arg, gchar * logfile, 
 		if (lp)
 		{
 			model = gtk_tree_view_get_model (GTK_TREE_VIEW(logw->treeview));
+#if 0
 			for (i = logw->qsos - first; i >= logw->qsos - last; i--)
 			{
 				pathstr = g_strdup_printf ("%d", i);
@@ -477,6 +514,37 @@ fields[j] == QTH || fields[j] == U1 || f
 				gtk_tree_path_free (path);
 				g_free (pathstr);
 			}
+#else
+			exported = last - first + 1;
+			sorteditems = g_new0 (item_t, exported);
+			for (i = logw->qsos - first; i >= logw->qsos - last; i--)
+			{
+				pathstr = g_strdup_printf ("%d", i);
+				path = gtk_tree_path_new_from_string (pathstr);
+				gtk_tree_model_get_iter (model, &iter, path);
+				for (j = 0; j < logw->columns; j++)
+				{
+					gtk_tree_model_get
+						(model, &iter, logw->logfields[j], &sorteditems[i-first+1][fields[j]], -1);
+					if (fields[j] == DATE || fields[j] == NAME ||
+fields[j] == QTH || fields[j] == U1 || fields[j] == U2 || fields[j] == REMARKS)
+						sorteditems[i-first+1][fields[j]] = g_locale_from_utf8
+							(sorteditems[i-first+1][fields[j]], -1, NULL, NULL, NULL);
+				}
+				gtk_tree_path_free (path);
+				g_free (pathstr);
+			}
+			if (preferences.tsvsortbydxcc)
+				qsort(sorteditems, exported, sizeof(gchar*)*QSO_FIELDS, &savelog_compar_sortbydxcc);
+			else if (preferences.tsvgroupbycallsign > 1)
+				qsort(sorteditems, exported, sizeof(gchar*)*QSO_FIELDS, &savelog_compar_groupbycall);
+
+			for (i = exported-1; i >= 0; i--)
+			{
+				log_file_qso_append (lp, sorteditems[i]);
+			}
+			g_free(sorteditems);
+#endif
 			log_file_close (lp);
 			_exit (0);
 		}
Index: src/logfile/labels.c
===================================================================
RCS file: /sources/xlog/xlog/src/logfile/labels.c,v
retrieving revision 1.21
diff -u -p -r1.21 labels.c
--- src/logfile/labels.c	16 May 2008 07:38:19 -0000	1.21
+++ src/logfile/labels.c	24 Nov 2008 21:00:50 -0000
@@ -56,18 +56,30 @@ const struct log_ops labels_ops = {
 	.extension = ".labels",
 };
 
+typedef struct {
+	FILE *fp;
+	gint groupbycallsign;
+	gchar *prev_call;
+} labels_priv_t;
 /*
  * open for read
  */
 gint
 labels_open (LOGDB * handle)
 {
-	FILE *fp;
+	labels_priv_t *priv;
+
+	priv = g_new0(labels_priv_t, 1);
+	if (!priv)
+		return -1;
 
-	fp = fopen (handle->path, "r");
-	if (!fp)
+	priv->fp = fopen (handle->path, "r");
+	if (!priv->fp) {
+		g_free(priv);
 		return -1;
-	handle->priv = (gpointer) fp;
+	}
+	handle->priv = (gpointer) priv;
+	priv->groupbycallsign = preferences.tsvgroupbycallsign;
 
 	return 0;
 }
@@ -78,28 +90,52 @@ labels_open (LOGDB * handle)
 gint
 labels_create (LOGDB * handle)
 {
-	FILE *fp;
+	labels_priv_t *priv;
 
-	fp = fopen (handle->path, "w");
-	if (!fp)
+	priv = g_new0(labels_priv_t, 1);
+	if (!priv)
 		return -1;
-	handle->priv = (gpointer) fp;
+
+	priv->fp = fopen (handle->path, "w");
+	if (!priv->fp) {
+		g_free(priv);
+		return -1;
+	}
+	handle->priv = (gpointer) priv;
+	priv->groupbycallsign = preferences.tsvgroupbycallsign;
 	return 0;
 }
 
 void
 labels_close (LOGDB * handle)
 {
-	FILE *fp = (FILE *) handle->priv;
-	fclose (fp);
+	labels_priv_t *priv = (labels_priv_t*)handle->priv;
+	if (priv->prev_call) {
+		g_free(priv->prev_call);
+		priv->prev_call = NULL;
+	}
+	fprintf (priv->fp, "\n");
+	fclose (priv->fp);
+	g_free(priv);
 }
 
 gint
 labels_qso_append (LOGDB * handle, const qso_t * q)
 {
-	FILE *fp = (FILE *) handle->priv;
+	labels_priv_t *priv = (labels_priv_t*)handle->priv;
+	FILE *fp = priv->fp;
 	gint kms, miles, l, result;
 
+	if (priv->prev_call && (strcmp(q[CALL],priv->prev_call) || --priv->groupbycallsign <= 0)) {
+		fprintf (fp, "\n");
+		priv->groupbycallsign = preferences.tsvgroupbycallsign;
+	}
+	if (priv->prev_call) {
+		g_free(priv->prev_call);
+		priv->prev_call = NULL;
+	}
+	priv->prev_call = g_strdup(q[CALL]);
+
 	if (preferences.saveastsv2[0] == 1)
 	{
 		if (q[DATE]) fprintf (fp, "%s\t", q[DATE]); else fprintf (fp, "\t");
@@ -199,7 +235,6 @@ labels_qso_append (LOGDB * handle, const
 	{
 		if (q[REMARKS]) fprintf (fp, "%s\t", q[REMARKS]); else fprintf (fp, "\t");
 	}
-	fprintf (fp, "\n");
 	return 0;
 }
 

Reply to: