/* * xlog - GTK+ logging program for amateur radio operators * Copyright (C) 2001-2002 Joop Stakenborg * * This program is free oftware; 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. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include "logfile.h" #include "types.h" /* * fields to be stored in the flog file */ const gint qso_fields[] = { DATE, GMT, CALL, BAND, MODE, RST, MYRST, QSLOUT, QSLIN, REMARKS }; const gint qso_widths[] = { 15, 8, 15, 15, 8, 15, 15, 8, 8, 80 }; const gint qso_field_nr = 10; extern const struct log_ops old_log_ops; extern const struct log_ops flog_ops; extern const struct log_ops twlog_ops; extern const struct log_ops adif_ops; extern const struct log_ops cabrillo_ops; extern const struct log_ops editest_ops; LOGDB* log_file_open(const gchar *path, enum log_file_type type) { LOGDB *handle; handle = (LOGDB*)g_malloc(sizeof(LOGDB)); if (!handle) return NULL; handle->type = type; switch (type) { case TYPE_FLOG: handle->ops = &flog_ops; break; case TYPE_OLD_LOG: handle->ops = &old_log_ops; break; case TYPE_TWLOG: handle->ops = &twlog_ops; break; case TYPE_ADIF: handle->ops = &adif_ops; break; case TYPE_CABRILLO: handle->ops = &cabrillo_ops; break; case TYPE_EDITEST: handle->ops = &editest_ops; break; default: /* unsupported log file type */ g_free(handle); return NULL; } handle->path = g_strdup(path); handle->column_nr = 0; if (handle->ops->open(handle)) { g_free(handle->path); g_free(handle); handle = NULL; } return handle; } LOGDB *log_file_create(const gchar *path, enum log_file_type type, gint columns, const gint column_fields[], const gint column_widths[]) { LOGDB *handle; handle = (LOGDB*)g_malloc(sizeof(LOGDB)); if (!handle) return NULL; handle->type = type; switch (type) { case TYPE_FLOG: handle->ops = &flog_ops; break; case TYPE_OLD_LOG: handle->ops = &old_log_ops; break; case TYPE_TWLOG: handle->ops = &twlog_ops; break; case TYPE_ADIF: handle->ops = &adif_ops; break; case TYPE_CABRILLO: handle->ops = &cabrillo_ops; break; case TYPE_EDITEST: handle->ops = &editest_ops; break; default: /* unsupported log file type */ g_free(handle); return NULL; } handle->path = g_strdup(path); handle->column_nr = columns; memcpy(handle->column_fields, column_fields, columns*sizeof(gint)); memcpy(handle->column_widths, column_widths, columns*sizeof(gint)); if (handle->ops->create(handle)) { g_free(handle->path); g_free(handle); handle = NULL; } return handle; } void log_file_close(LOGDB *handle) { handle->ops->close(handle); g_free(handle->path); g_free(handle); } gint log_file_qso_append(LOGDB *handle, const qso_t *q) { return handle->ops->qso_append(handle, q); } gint log_file_qso_foreach(LOGDB *handle, gint (*fn)(LOGDB*, qso_t*, gpointer arg), gpointer arg) { return handle->ops->qso_foreach(handle, fn, arg); } #if 0 /* this is for live surgery */ gint log_file_add_column(LOGDB *handle, gint pos, gint field, gint width) { g_array_insert_val(handle->column_widths, pos, width); g_array_insert_val(handle->column_fields, pos, field); return handle->ops->add_column(handle, pos, field, width); } gint log_file_delete_column(LOGDB *handle, gint pos) { g_array_remove_index(handle->column_widths, pos); g_array_remove_index(handle->column_fields, pos); return handle->ops->delete_column(handle, pos); } #endif /* * flog fields names */ static const gchar* field_strings[] = { "NR", "DATE", "GMT", "GMTEND", "CALL", "BAND", "MODE", "RST", "MYRST", "QSLOUT", "QSLIN", "POWER", "NAME", "QTH", "LOCATOR", "U1", "U2", "REMARKS" }; static const gint field_widths[] = { 8, 15, 8, 8, 15, 15, 8, 15, 15, 8, 8, 8, 30, 30, 8, 30, 30, 80 }; gint parse_field_name(const gchar *s) { gint i; for (i = 0; i < QSO_FIELDS; i++) { if (!strcmp(s, field_strings[i])) return i; } return -1; } gint parse_field_width(const gint field) { /* better know what you're doing */ if (field >= QSO_FIELDS || field < 0) return 0; return field_widths[field]; } const gchar *strfield(gint field) { /* better know what you're doing */ if (field >= QSO_FIELDS || field < 0) return NULL; return field_strings[field]; } size_t strftime(char *s, size_t max, const char *format, const struct tm *tm); gint scan_month(const gchar *s) { int i; static gchar month_abv[12][4] = {"","","","","","","","","","","",""}; static struct tm timestruct = { 0, 0, 0, 1, 0, 0, 0, 0, 0 }; /* * get locale month abreviations */ if (!month_abv[0]) { for (i = 0; i < 12; i++) { timestruct.tm_mon = i; strftime (month_abv[i], 3, "%b", ×truct); } } for (i = 0; i < 12; i++) { if (!strncasecmp(s, month_abv[i], 3)) return i+1; } /* fall back to english abreviations */ switch (tolower(s[0])) { case 'j': if (s[1] == 'a') return 1; else if (s[2] == 'n') return 6; else return 7; case 'f': return 2; case 'm': if (s[2] == 'r') return 3; else return 5; case 'a': if (s[2] == 'r') return 4; else return 8; case 's': return 9; case 'o': return 10; case 'n': return 11; case 'd': return 12; default: return 0; } }