diff --git a/logbook/adif.cpp b/logbook/adif.cpp index 2a69e3058..fa2802cc2 100644 --- a/logbook/adif.cpp +++ b/logbook/adif.cpp @@ -6,6 +6,7 @@ /* W1XT20m14.076DM33JT65-21-14201104220417042441st JT65A QSO. Him: mag loop 20WVK3ACFqf22lb IK1SOW20m14.076JN35JT65-19-1120110422052505333VK3ACFqf22lb +W4ABC> ... */ void ADIF::init(QString filename) @@ -14,25 +15,36 @@ void ADIF::init(QString filename) _data.clear(); } + QString ADIF::_extractField(const QString line, const QString fieldName) { - int s1 = line.indexOf(fieldName,0,Qt::CaseInsensitive); - if (s1 >=0) + int fieldNameIndex = line.indexOf(fieldName,0,Qt::CaseInsensitive); + if (fieldNameIndex >=0) { - int s2 = line.indexOf('>',s1); - if (s2 >= 0) - { - int flsi = s1+fieldName.length(); - int flsl = s2-flsi; - if (flsl>0) - { - QString fieldLengthString = line.mid(flsi,flsl); - int fieldLength = fieldLengthString.toInt(); - QString field = line.mid(s2+1,fieldLength); + int closingBracketIndex = line.indexOf('>',fieldNameIndex); + int fieldLengthIndex = line.indexOf(':',fieldNameIndex); // find the size delimiter + int dataTypeIndex = -1; + if (fieldLengthIndex >= 0) + { + dataTypeIndex = line.indexOf(':',fieldLengthIndex+1); // check for a second : indicating there is a data type + if (dataTypeIndex > closingBracketIndex) + dataTypeIndex = -1; // second : was found but it was beyond the closing > + } + + if ((closingBracketIndex > fieldNameIndex) && (fieldLengthIndex > fieldNameIndex) && (fieldLengthIndex< closingBracketIndex)) + { + int fieldLengthCharCount = closingBracketIndex - fieldLengthIndex -1; + if (dataTypeIndex >= 0) + fieldLengthCharCount -= 2; // data type indicator is always a colon followed by a single character + QString fieldLengthString = line.mid(fieldLengthIndex+1,fieldLengthCharCount); + int fieldLength = fieldLengthString.toInt(); + if (fieldLength > 0) + { + QString field = line.mid(closingBracketIndex+1,fieldLength); return field; - } + } } - } + } return ""; } @@ -44,20 +56,20 @@ void ADIF::load() QFile inputFile(_filename); if (inputFile.open(QIODevice::ReadOnly)) { - QTextStream in(&inputFile); - while ( !in.atEnd() ) - { - QString line = in.readLine(); - QSO q; - q.call = _extractField(line,"CALL:"); - q.band = _extractField(line,"BAND:"); - q.mode = _extractField(line,"MODE:"); - q.date = _extractField(line,"QSO_DATE:"); - if (q.call != "") - _data << q; - } - inputFile.close(); - } + QTextStream in(&inputFile); + while ( !in.atEnd() ) + { + QString line = in.readLine(); + QSO q; + q.call = _extractField(line,"CALL:"); + q.band = _extractField(line,"BAND:"); + q.mode = _extractField(line,"MODE:"); + q.date = _extractField(line,"QSO_DATE:"); + if (q.call != "") + _data.insert(q.call,q); + } + inputFile.close(); + } } @@ -68,45 +80,52 @@ void ADIF::add(const QString call) q.band = ""; //TODO q.mode = "JT9"; //TODO q.date = ""; //TODO - _data << q; + _data.insert(q.call,q); } // return true if in the log same band and mode (where JT65 == JT9) bool ADIF::match(const QString call, const QString band, const QString mode) { - QSO q; - foreach(q,_data) - { - if (call.compare(q.call) == 0) //TODO handle multiple log entries from same call, should this be a hash table rather than a list? - { - if ((band.compare(q.band) == 0) || (band=="") || (q.band=="")) - { - if ( - ( - ((mode.compare("JT65",Qt::CaseInsensitive)==0) || (mode.compare("JT9",Qt::CaseInsensitive)==0)) - && - ((q.mode.compare("JT65",Qt::CaseInsensitive)==0) || (q.mode.compare("JT9",Qt::CaseInsensitive)==0)) - ) - || (mode.compare(q.mode)==0) - ) - return true; - } - } - } + QList qsos = _data.values(call); + if (qsos.size()>0) + { + QSO q; + foreach(q,qsos) + { + if ( (band.compare(q.band) == 0) + || (band=="") + || (q.band=="")) + { + if ( + ( + ((mode.compare("JT65",Qt::CaseInsensitive)==0) || (mode.compare("JT9",Qt::CaseInsensitive)==0)) + && + ((q.mode.compare("JT65",Qt::CaseInsensitive)==0) || (q.mode.compare("JT9",Qt::CaseInsensitive)==0)) + ) + || (mode.compare(q.mode)==0) + || (mode=="") + ) + return true; + } + } + } return false; } QList ADIF::getCallList() { QList p; - QSO q; - foreach(q,_data) - p << q.call; + QMultiHash::const_iterator i = _data.constBegin(); + while (i != _data.constEnd()) + { + p << i.key(); + ++i; + } return p; } int ADIF::getCount() { - return _data.length(); + return _data.size(); } diff --git a/logbook/adif.h b/logbook/adif.h index 6082e969f..91d3ca555 100644 --- a/logbook/adif.h +++ b/logbook/adif.h @@ -11,6 +11,7 @@ #if defined (QT5) #include #include +#include #else #include #endif @@ -33,7 +34,7 @@ class ADIF QString call,band,mode,date; }; - QList _data; + QMultiHash _data; QString _filename; QString _extractField(const QString line, const QString fieldName); diff --git a/logbook/countriesworked.h b/logbook/countriesworked.h index 87287e2b4..34fcc0c0b 100644 --- a/logbook/countriesworked.h +++ b/logbook/countriesworked.h @@ -6,7 +6,10 @@ #ifndef __COUNTRIESWORKDED_H #define __COUNTRIESWORKDED_H -#include +#include +#include +#include +#include class CountriesWorked diff --git a/logbook/countrydat.cpp b/logbook/countrydat.cpp index 2cac9b739..cc71ab184 100644 --- a/logbook/countrydat.cpp +++ b/logbook/countrydat.cpp @@ -29,8 +29,12 @@ void CountryDat::init(const QString filename) QString CountryDat::_extractName(const QString line) { int s1 = line.indexOf(':'); - QString name = line.mid(0,s1); - return name; + if (s1>=0) + { + QString name = line.mid(0,s1); + return name; + } + return ""; } void CountryDat::_removeBrackets(QString &line, const QString a, const QString b) @@ -71,7 +75,7 @@ QStringList CountryDat::_extractPrefix(QString &line, bool &more) void CountryDat::load() { - _data.clear(); //dictionary was = {} + _data.clear(); _countryNames.clear(); //used by countriesWorked QFile inputFile(_filename); @@ -86,23 +90,26 @@ void CountryDat::load() QString line2 = in.readLine(); QString name = _extractName(line1); - _countryNames << name; - bool more = true; - QStringList prefixs; - while (more) - { - QStringList p = _extractPrefix(line2,more); - prefixs += p; - if (more) - line2 = in.readLine(); - } - - QString p; - foreach(p,prefixs) + if (name.length()>0) { - if (p.length() > 0) - _data.insert(p,name); - } + _countryNames << name; + bool more = true; + QStringList prefixs; + while (more) + { + QStringList p = _extractPrefix(line2,more); + prefixs += p; + if (more) + line2 = in.readLine(); + } + + QString p; + foreach(p,prefixs) + { + if (p.length() > 0) + _data.insert(p,name); + } + } } } inputFile.close(); diff --git a/logbook/countrydat.h b/logbook/countrydat.h index 971b614f6..968bc6a77 100644 --- a/logbook/countrydat.h +++ b/logbook/countrydat.h @@ -8,7 +8,10 @@ #ifndef __COUNTRYDAT_H #define __COUNTRYDAT_H -#include + +#include +#include +#include class CountryDat diff --git a/logbook/logbook.cpp b/logbook/logbook.cpp index b627b9dae..68b52ce5d 100644 --- a/logbook/logbook.cpp +++ b/logbook/logbook.cpp @@ -1,5 +1,5 @@ #include "logbook.h" - +#include void LogBook::init() { @@ -58,7 +58,7 @@ void LogBook::match(/*in*/const QString call, countryWorkedBefore = false; } } - qDebug() << "Logbook:" << call << ":" << countryName << "Cty B4:" << countryWorkedBefore << "call B4:" << callWorkedBefore; + //qDebug() << "Logbook:" << call << ":" << countryName << "Cty B4:" << countryWorkedBefore << "call B4:" << callWorkedBefore; } void LogBook::addAsWorked(const QString call) diff --git a/logbook/logbook.h b/logbook/logbook.h index a4722e192..223412d11 100644 --- a/logbook/logbook.h +++ b/logbook/logbook.h @@ -7,7 +7,7 @@ #define LOGBOOK_H -#include +#include #include "countrydat.h" #include "countriesworked.h" diff --git a/mainwindow.cpp b/mainwindow.cpp index 06de5031f..d75e96383 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1,4 +1,4 @@ -//------------------------------------------------------------- MainWindow +//-------------------------------------------------------------- MainWindow #include "mainwindow.h" #include "ui_mainwindow.h" diff --git a/mainwindow.ui b/mainwindow.ui index 3915402e7..b854d4ab6 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -2223,7 +2223,7 @@ p, li { white-space: pre-wrap; } 0 0 760 - 21 + 20 @@ -2615,7 +2615,7 @@ p, li { white-space: pre-wrap; } true - Show DXCC entity and B4 status + Show DXCC entity and worked B4 status