/* * xlog - GTK+ logging program for amateur radio operators * Copyright (C) 2001-2005 Joop Stakenborg * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * table.c - table lookups and creation of the hashtable */ #include #include #include #include "support.h" #include "tables.h" #include "types.h" #include "gc.h" extern GtkWidget *mainwindow; extern statetype state; extern preferencestype preferences; GPtrArray *table; GHashTable *prefixes; static void table_add (gchar *pfx, gchar *name, guint cont, gint tz, gint lat, gint lon, gchar *itu, gchar *cq, gint dxcc, gchar *w, gchar *d) { dxcc_data *new_data = g_new (dxcc_data, 1); new_data -> px = g_strdup (pfx); new_data -> countryname = g_strdup (name); new_data -> continent = cont; new_data -> timezone = tz; new_data -> latitude = lat; new_data -> longitude = lon; new_data -> ituzones = g_strdup (itu); new_data -> cqzones = g_strdup (cq); new_data -> dxcc = dxcc; new_data -> whatitis = g_strdup (w); new_data -> date = g_strdup (d); g_ptr_array_add (table, new_data); } /* * format of the table to be read: vertical bar separated data with linefeeds * field 1: valid prefixes separated by a comma * field 2: name of the country * field 3: continent as an integer, EU=1,NA=2,SA=3,AS=4,AF=5,OC=6,AN=7 * field 4: timezone as an integer, to be divided by 10. * field 5: latitude as an integer, to be divided by 100. * field 6: longitude as an integer, to be divided by 100. * field 7: itu zones, comma separated * field 8: cq zones, comma separated * field 9: DXCC reference number (integer), blank if a call area * field 10: D=Deleted, R=Region * field 11: The date range for which the entry is effective * and/or dxcc assignment */ gint readtable (void) { gchar *t_location, **split, **pfx; FILE *fp; gchar buf[50000]; gint i = 0, ch = 0, j, line = 1; t_location = g_strconcat (XLOG_DATADIR, G_DIR_SEPARATOR_S, "tables", G_DIR_SEPARATOR_S, "dxcctable.txt", NULL); if ((fp = fopen (t_location, "r")) == NULL) { g_free (t_location); return 1; } table = g_ptr_array_new (); prefixes = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)g_free, NULL); /* first field in case hash_table_lookup returns NULL */ table_add ("", "", -1, -1, 0, 0 ,"", "", 0, "", ""); while (!feof (fp)) { while (ch != 10) { ch = fgetc (fp); if (ch == EOF) break; buf[i++] = ch; } if (ch == EOF) break; buf[i] = '\0'; i = 0; ch = 0; split = g_strsplit (buf, "|", 11); table_add (split[0], split[1], atoi(split[2]), atoi(split[3]), atoi(split[4]), atoi(split[5]), split[6], split[7], atoi(split[8]), split[9], split[10]); /* make a prefix list */ pfx = g_strsplit (split[0], ",", 0); for (j = 0;; j++) { if (!pfx[j]) break; g_hash_table_insert (prefixes, g_strdup (pfx[j]), GINT_TO_POINTER (line)); } g_strfreev (pfx); g_strfreev (split); line++; } fclose (fp); g_free (t_location); return 0; } void cleanup_table (void) { } /* replace callsign area: UA9IA/0 -> UA0IA */ static gchar * replace (gchar *c, gint area) { gchar *end, *j; end = c + strlen (c); for (j = c; j < end; ++j) { switch (*j) { case '0' ... '9': if ((j - c) > 1) *j = area + 48; break; } } return(g_strdup(c)); } /* extract prefix from a c */ static gchar * getpx (gchar *checkcall) { gchar *px, **split; /* characters after '/' might contain a country */ if (strchr(checkcall, '/')) { split = g_strsplit(checkcall, "/", 2); if (split[1]) /* we might be typing */ { if ((strlen(split[1]) > 1) && (strlen(split[1]) < strlen(split[0]))) /* this might be a candidate */ { if (g_ascii_strcasecmp(split[1], "QRP") == 0) px = g_strdup(split[0]); else px = g_strdup(split[1]); } else if ((strlen(split[1]) == 1) && atoi(split[1])) /* c area changed */ { px = replace(split[0], atoi(split[1])); } else px = g_strdup(split[0]); } else px = g_strdup(split[0]); g_strfreev(split); } else px = g_strdup(checkcall); return(px); } /* lookup the callsign in the hastable */ static gint lookup_dxcc (gchar * c) { gint i, country = 0; gchar *px, *searchpx; px = getpx(c); if (px) { for (i = strlen(px); i > 0; i--) { searchpx = g_strndup (px, i); country = GPOINTER_TO_INT(g_hash_table_lookup (prefixes, searchpx)); if (country > 0) { g_free (searchpx); break; } } g_free (px); } else country = 0; return (country); } void updatetableframe (gchar *c) { GtkWidget *dxcclabel1, *dxcclabel2, *dxcclabel3, *dxcclabel4, *dxcclabel5, *dxccframe, *framelabel; gchar *labeltext1, *cont, *labeltext2, *labeltext3, *labeltext4, *gcresult; gint country = -1; dxcclabel1 = lookup_widget (mainwindow, "dxcclabel1"); dxcclabel2 = lookup_widget (mainwindow, "dxcclabel2"); dxcclabel3 = lookup_widget (mainwindow, "dxcclabel3"); dxcclabel4 = lookup_widget (mainwindow, "dxcclabel4"); dxcclabel5 = lookup_widget (mainwindow, "dxcclabel5"); dxccframe = lookup_widget (mainwindow, "dxccframe"); labeltext1 = g_strdup (""); labeltext2 = g_strdup (""); labeltext3 = g_strdup (""); labeltext4 = g_strdup (""); gcresult = g_strdup (""); framelabel = gtk_frame_get_label_widget (GTK_FRAME(dxccframe)); gtk_label_set_text (GTK_LABEL (framelabel), "DXCC"); if (g_ascii_strcasecmp (c, "") != 0) { country = lookup_dxcc (c); gtk_label_set_text (GTK_LABEL (framelabel), c); } if (country > 0) { dxcc_data *t = g_ptr_array_index (table, country); labeltext1 = g_strdup_printf ("%s", t->countryname); switch (t->continent) { case 1: cont = g_strdup ("EU"); break; case 2: cont = g_strdup ("NA"); break; case 3: cont = g_strdup ("SA"); break; case 4: cont = g_strdup ("AS"); break; case 5: cont = g_strdup ("AF"); break; case 6: cont = g_strdup ("OC"); break; case 7: cont = g_strdup ("AN"); break; default: cont = g_strdup ("??"); break; } labeltext2 = g_strdup_printf ("%s - ITU %s - CQ %s", cont, t->ituzones, t->cqzones); g_free (cont); labeltext3 = g_strdup_printf (_("Timezone: %+1.1f"), (gdouble) t->timezone / 10); labeltext4 = g_strdup_printf (_("Location: %+1.2f %+1.2f"), (gdouble) t->latitude / 100, (gdouble) t->longitude / 100); gcresult = g_strdup_printf ("%s", gc(preferences.units, state.mylocation, (gdouble) t->latitude / 100, (gdouble) t->longitude / 100)); } gtk_label_set_markup (GTK_LABEL (dxcclabel1), labeltext1); gtk_label_set_text (GTK_LABEL (dxcclabel2), labeltext2); gtk_label_set_text (GTK_LABEL (dxcclabel3), labeltext3); gtk_label_set_text (GTK_LABEL (dxcclabel4), labeltext4); gtk_label_set_markup (GTK_LABEL (dxcclabel5), gcresult); g_free (labeltext1); g_free (labeltext2); g_free (labeltext3); g_free (labeltext4); g_free (gcresult); }