From 718522277d8756bf2d8c4a92a0df7ccff753e062 Mon Sep 17 00:00:00 2001 From: Stelios Bounanos Date: Wed, 4 Feb 2009 05:20:24 +0000 Subject: [PATCH] Add LoTW and eQSL hints to dxcc popup This uses the following files: * http://www.hb9bza.net/lotw/lotw1.txt in ~/.fldigi/lotw1.txt * http://www.eqsl.cc/QSLCard/DownloadedFiles/AGMemberList.txt in ~/.fldigi/AGMemberList.txt or ~/.fldigi/eqsl.txt Also changed the FText tooltip display function to use a string stream --- src/include/dxcc.h | 7 +++++ src/main.cxx | 5 ++++ src/misc/dxcc.cxx | 49 ++++++++++++++++++++++++++++++++ src/widgets/FTextView.cxx | 59 +++++++++++++++++++++------------------ 4 files changed, 93 insertions(+), 27 deletions(-) diff --git a/src/include/dxcc.h b/src/include/dxcc.h index e0a9a66d..1bbed0d9 100644 --- a/src/include/dxcc.h +++ b/src/include/dxcc.h @@ -13,8 +13,15 @@ struct dxcc { float lat = 0.0f, float lon = 0.0f, float tz = 0.0f); }; +enum qsl_t { QSL_LOTW, QSL_EQSL, QSL_END }; +extern const char* qsl_names[]; + bool dxcc_open(const char* filename); void dxcc_close(void); const dxcc* dxcc_lookup(const char* callsign); +bool qsl_open(const char* filename, qsl_t qsl_type); +void qsl_close(void); +unsigned char qsl_lookup(const char* callsign); + #endif // DXCC_H_ diff --git a/src/main.cxx b/src/main.cxx index 88a8ee86..f21bd372 100644 --- a/src/main.cxx +++ b/src/main.cxx @@ -312,6 +312,11 @@ int main(int argc, char ** argv) if (progdefaults.rxtext_tooltips || progdefaults.autofill_qso_fields) dxcc_open(string(HomeDir).append("cty.dat").c_str()); + if (progdefaults.rxtext_tooltips) { + qsl_open(string(HomeDir).append("lotw1.txt").c_str(), QSL_LOTW); + if (!qsl_open(string(HomeDir).append("eqsl.txt").c_str(), QSL_EQSL)) + qsl_open(string(HomeDir).append("AGMemberList.txt").c_str(), QSL_EQSL); + } int ret = Fl::run(); diff --git a/src/misc/dxcc.cxx b/src/misc/dxcc.cxx index 8fd80a26..1f3f8bd3 100644 --- a/src/misc/dxcc.cxx +++ b/src/misc/dxcc.cxx @@ -186,3 +186,52 @@ static void add_prefix(string& prefix, dxcc* entry) prefix.erase(first); prev_entry = cmap->insert(prev_entry, make_pair(prefix, entry)); } + +typedef map qsl_map; +static qsl_map* qsl_calls; +const char* qsl_names[] = { "LoTW", "eQSL" }; + +bool qsl_open(const char* filename, qsl_t qsl_type) +{ + ifstream in(filename); + if (!in) + return false; + if (!qsl_calls) + qsl_calls = new qsl_map; + + size_t n = qsl_calls->size(); + qsl_map::iterator prev_entry = qsl_calls->begin(); + string::size_type p; + string s; + s.reserve(32); + while (getline(in, s)) { + if ((p = s.rfind('\r')) != string::npos) + s.erase(p); + prev_entry = qsl_calls->insert(prev_entry, make_pair(s, 0)); + prev_entry->second |= (1 << qsl_type); + } + + LOG_INFO("Added %zu %s callsigns from \"%s\"", + qsl_calls->size() - n, qsl_names[qsl_type], filename); + + return true; +} + +void qsl_close(void) +{ + delete qsl_calls; + qsl_calls = 0; +} + +unsigned char qsl_lookup(const char* callsign) +{ + if (qsl_calls == 0) + return 0; + + string str; + str.resize(strlen(callsign)); + transform(callsign, callsign + str.length(), str.begin(), static_cast(toupper)); + + qsl_map::const_iterator i = qsl_calls->find(str); + return i == qsl_calls->end() ? 0 : i->second; +} diff --git a/src/widgets/FTextView.cxx b/src/widgets/FTextView.cxx index f8c60dee..ca6cc6a6 100644 --- a/src/widgets/FTextView.cxx +++ b/src/widgets/FTextView.cxx @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -893,7 +894,6 @@ loop: const char* FTextView::dxcc_lookup_call(int x, int y) { char* s = get_word(x - this->x(), y - this->y()); - const char* ret = 0; if (!(s && *s && call.match(s))) { free(s); return 0; @@ -901,14 +901,16 @@ const char* FTextView::dxcc_lookup_call(int x, int y) const char *name = 0, *date = 0, *qth = 0, *locator = 0, *mode; double lon1, lat1, lon2 = 360.0, lat2 = 360.0, distance, azimuth; - static char tip[256]; - size_t len = 0; + static string tip; + ostringstream stip; const dxcc* e = 0; cQsoRec* qso = 0; + unsigned char qsl; e = dxcc_lookup(s); + qsl = qsl_lookup(s); qso = SearchLog(s); - + if (qso) { locator = qso->getField(GRIDSQUARE); if (!(locator && *locator && locator2longlat(&lon2, &lat2, locator) == RIG_OK)) @@ -916,44 +918,47 @@ const char* FTextView::dxcc_lookup_call(int x, int y) name = qso->getField(NAME); date = qso->getField(QSO_DATE); qth = qso->getField(QTH); - } if (e) { if (lon2 == 360.0) lon2 = -e->longitude; if (lat2 == 360.0) lat2 = e->latitude; - len += snprintf(tip, sizeof(tip), "%s (%s GMT%+0.1f) CQ-%d ITU-%d\n", - e->country, e->continent, -e->gmt_offset, e->cq_zone, e->itu_zone); - ret = tip; + stip << e->country << " (" << e->continent + << " GMT" << fixed << showpos << setprecision(1) << -e->gmt_offset << noshowpos + << ") CQ-" << e->cq_zone << " ITU-" << e->itu_zone << '\n'; } - if (len < sizeof(tip) && locator2longlat(&lon1, &lat1, progdefaults.myLocator.c_str()) == RIG_OK && + if (locator2longlat(&lon1, &lat1, progdefaults.myLocator.c_str()) == RIG_OK && qrb(lon1, lat1, lon2, lat2, &distance, &azimuth) == RIG_OK) { - len += snprintf(tip + len, sizeof(tip) - len, "QTE %.0f\260 (%.0f\260) QRB %.0fkm (%.0fkm)\n", - azimuth, azimuth_long_path(azimuth), distance, distance_long_path(distance)); - ret = tip; + stip << "QTE " << setprecision(0) << azimuth << '\260' << " (" + << azimuth_long_path(azimuth) << '\260' << ") QRB " << distance << "km (" + << distance_long_path(distance) << "km)\n"; } - if (len < sizeof(tip) && name && *name) { - len += snprintf(tip + len, sizeof(tip) - len, "* %s", name); - if (len < sizeof(tip) && qth && *qth) - len += snprintf(tip + len, sizeof(tip) - len, " %s %s\n", _("in"), qth); - else if (len + 1 < sizeof(tip)) { - tip[len++] = '\n'; - tip[len] = '\0'; - } - ret = tip; + if (name && *name) { + stip << "* " << name; + if (qth && *qth) + stip << ' ' << _("in") << ' ' << qth; + stip << '\n'; } - if (len < sizeof(tip) && date && *date) { - len += snprintf(tip + len, sizeof(tip) - len, "* %s: %s", _("Last QSO"), date); + if (date && *date) { + stip << "* " << _("Last QSO") << ": " << date; mode = qso->getField(MODE); - if (len < sizeof(tip) && mode && *mode) - len += snprintf(tip + len, sizeof(tip) - len, " %s %s", _("in"), mode); - ret = tip; + if (mode) + stip << ' ' << _("in") << ' ' << mode; + stip << '\n'; + } + if (qsl) { + stip << "* "; + for (unsigned char i = 0; i < QSL_END; i++) + if (qsl & (1 << i)) + stip << qsl_names[i] << ' '; + stip << '\n'; } free(s); - return ret; + tip = stip.str(); + return tip.empty() ? 0 : tip.c_str(); } void FTextView::dxcc_tooltip(void* obj)