From 1fe431b99e2203ef68b92af99fe028feff5e5ca3 Mon Sep 17 00:00:00 2001 From: Lorenzo Buzzi Date: Sat, 6 Jul 2024 11:14:17 +0200 Subject: [PATCH 1/5] Club and Team are now separate details This makes it possible to distinguish between Teams from the same Club, while maintaining the possibility of creating rankings per club (that in the UI are called 'Team Rankings'). --- chronorace.ui | 12 +- chronoracedata.cpp | 2 +- classentry.cpp | 97 ++++-- classentry.hpp | 11 +- competitor.cpp | 31 +- competitor.hpp | 14 +- crloader.cpp | 4 +- csvrankingprinter.cpp | 12 +- lbchronorace.cpp | 12 +- lbchronorace.hpp | 4 +- pdfrankingprinter.cpp | 10 +- rankingsbuilder.cpp | 10 +- samples/mass_start/latin1/startlist.csv | 374 ++++++++++++------------ samples/mass_start/mass_start.crd | Bin 903330 -> 904082 bytes samples/mass_start/utf8/startlist.csv | 374 ++++++++++++------------ samples/relay/latin1/startlist.csv | 246 ++++++++-------- samples/relay/relay.crd | Bin 897980 -> 897730 bytes startlistmodel.cpp | 86 +++++- startlistmodel.hpp | 10 +- teamclassentry.cpp | 10 +- teamclassentry.hpp | 4 +- teamslistmodel.cpp | 33 +-- teamslistmodel.hpp | 3 - translations/LBChronoRace_en.ts | 56 ++-- translations/LBChronoRace_it.ts | 56 ++-- txtrankingprinter.cpp | 12 +- 26 files changed, 810 insertions(+), 673 deletions(-) diff --git a/chronorace.ui b/chronorace.ui index 3b79594..b0bfcd9 100644 --- a/chronorace.ui +++ b/chronorace.ui @@ -58,15 +58,15 @@ - + true - See the list of the teams (that cannot be changed) + See the list of the clubs (that cannot be changed) - Edit Teams List + View Clubs List @@ -503,10 +503,10 @@ :/material/icons/format_list_bulleted.svg:/material/icons/format_list_bulleted.svg - Te&ams + Cl&ubs - See the list of the teams (that cannot be changed) + See the list of the clubs (that cannot be changed) @@ -595,7 +595,7 @@ saveRace editRace editStartList - editTeamsList + editClubsList editCategories editTimings diff --git a/chronoracedata.cpp b/chronoracedata.cpp index d3f5ebd..71badb1 100644 --- a/chronoracedata.cpp +++ b/chronoracedata.cpp @@ -126,7 +126,7 @@ QDataStream &operator>>(QDataStream &in, ChronoRaceData &data) >> data.sponsorLogo3.pixmap >> data.sponsorLogo4.pixmap; - if (data.binFmt == LBCHRONORACE_BIN_FMT_v2) + if (data.binFmt > LBCHRONORACE_BIN_FMT_v1) in >> data.stringFields[static_cast(ChronoRaceData::StringField::LENGTH)] >> data.stringFields[static_cast(ChronoRaceData::StringField::ELEVATION_GAIN)]; diff --git a/classentry.cpp b/classentry.cpp index 80abc32..5bc723d 100644 --- a/classentry.cpp +++ b/classentry.cpp @@ -99,9 +99,10 @@ QString ClassEntry::getNamesCommon(bool csvFormat) const for (i = 0; i < entries.size(); i++) { if ((c = entries[i].competitor)) { + QString clubAndTeam = QString("%1 %2").arg(c->getClub(), c->getTeam()).simplified(); retString += csvFormat ? - QString(",%1").arg(c->getTeam()) : - QString(" - %1").arg(c->getTeam(), -teamNameWidthMax); + QString(",%1").arg(clubAndTeam) : + QString(" - %1").arg(clubAndTeam, -teamNameWidthMax); break; } } @@ -117,14 +118,26 @@ QString ClassEntry::getNamesCommon(bool csvFormat) const return retString; } -QString ClassEntry::getNamesCSV() const +QString ClassEntry::getNames(CRLoader::Format format) const { - return getNamesCommon(true); -} + QString retString; -QString ClassEntry::getNamesTxt() const -{ - return getNamesCommon(false); + switch (format) + { + case CRLoader::Format::TEXT: + retString = getNamesCommon(false); + break; + case CRLoader::Format::CSV: + retString = getNamesCommon(true); + break; + case CRLoader::Format::PDF: + [[fallthrough]]; + default: + retString = "***Error***"; + break; + } + + return retString; } uint ClassEntry::getYear(uint legIdx) const @@ -157,22 +170,26 @@ Competitor::Sex ClassEntry::getSex(uint legIdx) const return (entries[legIdx].competitor) ? entries[legIdx].competitor->getSex() : Competitor::Sex::UNDEFINED; } -QString ClassEntry::getTimesCSV() const -{ - QString retString; - - for (QVector::ConstIterator it = entries.constBegin(); it < entries.constEnd(); it++) - retString.append(QString("%1%2,%3").arg((it == entries.constBegin()) ? "" : ",").arg(it->legRanking).arg(Timing::toTimeStr(it->time, Timing::Status::CLASSIFIED))); - - return retString; -} - -QString ClassEntry::getTimesTxt(int legRankWidth) const +QString ClassEntry::getTimes(CRLoader::Format format, int legRankWidth) const { QString retString; - for (QVector::ConstIterator it = entries.constBegin(); it < entries.constEnd(); it++) - retString.append(QString("%1(%2) %3").arg((it == entries.constBegin()) ? "" : " - ").arg(it->legRanking, legRankWidth).arg(Timing::toTimeStr(it->time, it->status), 7)); + switch (format) + { + case CRLoader::Format::TEXT: + for (QVector::ConstIterator it = entries.constBegin(); it < entries.constEnd(); it++) + retString.append(QString("%1(%2) %3").arg((it == entries.constBegin()) ? "" : " - ").arg(it->legRanking, legRankWidth).arg(Timing::toTimeStr(it->time, it->status), 7)); + break; + case CRLoader::Format::CSV: + for (QVector::ConstIterator it = entries.constBegin(); it < entries.constEnd(); it++) + retString.append(QString("%1%2,%3").arg((it == entries.constBegin()) ? "" : ",").arg(it->legRanking).arg(Timing::toTimeStr(it->time, Timing::Status::CLASSIFIED))); + break; + case CRLoader::Format::PDF: + [[fallthrough]]; + default: + retString = "***Error***"; + break; + } return retString; } @@ -280,6 +297,16 @@ uint ClassEntry::getToYear() const return toYear; } +QString const &ClassEntry::getClub() const +{ + for (auto const &it : entries) { + if (it.competitor) + return it.competitor->getClub(); + } + + return ClassEntry::empty; +} + QString const &ClassEntry::getTeam() const { for (auto const &it : entries) { @@ -327,16 +354,28 @@ uint ClassEntry::getTotalTime() const return totalTime; } -QString ClassEntry::getTotalTimeCSV() const +QString ClassEntry::getTotalTime(CRLoader::Format format) const { - return getTotalTimeTxt(); -} + QString retString; -QString ClassEntry::getTotalTimeTxt() const -{ - if (isDns()) return Timing::toTimeStr(totalTime, Timing::Status::DNS); - if (isDnf()) return Timing::toTimeStr(totalTime, Timing::Status::DNF); - return Timing::toTimeStr(totalTime, Timing::Status::CLASSIFIED); + switch (format) + { + case CRLoader::Format::TEXT: + case CRLoader::Format::CSV: + case CRLoader::Format::PDF: + if (isDns()) + retString = Timing::toTimeStr(totalTime, Timing::Status::DNS); + else if (isDnf()) + retString = Timing::toTimeStr(totalTime, Timing::Status::DNF); + else + retString = Timing::toTimeStr(totalTime, Timing::Status::CLASSIFIED); + break; + default: + retString = "***Error***"; + break; + } + + return retString; } QString ClassEntry::getDiffTimeTxt(uint referenceTime) const diff --git a/classentry.hpp b/classentry.hpp index 13a91da..eae0c65 100644 --- a/classentry.hpp +++ b/classentry.hpp @@ -21,6 +21,7 @@ #include #include +#include "crloader.hpp" #include "competitor.hpp" #include "timing.hpp" @@ -60,13 +61,11 @@ class ClassEntry { uint getBib() const; void setBib(uint newBib); QString getName(uint legIdx) const; - QString getNamesCSV() const; - QString getNamesTxt() const; + QString getNames(CRLoader::Format format) const; uint getYear(uint legIdx) const; Competitor::Sex getSex() const; Competitor::Sex getSex(uint legIdx) const; - QString getTimesCSV() const; - QString getTimesTxt(int legRankWidth) const; + QString getTimes(CRLoader::Format format, int legRankWidth = 0) const; QString getTime(uint legIdx) const; uint getTimeValue(uint legIdx) const; uint countEntries() const; @@ -75,10 +74,10 @@ class ClassEntry { void setLegRanking(uint legIdx, uint ranking); uint getFromYear() const; uint getToYear() const; + QString const &getClub() const; QString const &getTeam() const; uint getTotalTime() const; - QString getTotalTimeCSV() const; - QString getTotalTimeTxt() const; + QString getTotalTime(CRLoader::Format format) const; QString getDiffTimeTxt(uint referenceTime) const; bool isDnf() const; bool isDns() const; diff --git a/competitor.cpp b/competitor.cpp index 41d631c..9dafb48 100644 --- a/competitor.cpp +++ b/competitor.cpp @@ -15,6 +15,7 @@ * along with this program. If not, see . * *****************************************************************************/ +#include "lbchronorace.hpp" #include "competitor.hpp" #include "lbcrexception.hpp" @@ -27,6 +28,7 @@ QDataStream &operator<<(QDataStream &out, const Competitor &comp) << comp.name << Competitor::toSexString(comp.sex) << quint32(comp.year) + << comp.club << comp.team << quint32(comp.leg) << qint32(comp.offset); @@ -46,8 +48,10 @@ QDataStream &operator>>(QDataStream &in, Competitor &comp) >> comp.name >> sexStr >> year32 - >> comp.team - >> leg32 + >> comp.club; + if (LBChronoRace::binFormat > LBCHRONORACE_BIN_FMT_v2) + in >> comp.team; + in >> leg32 >> offset32; comp.bib = bib32; @@ -94,6 +98,27 @@ void Competitor::setSex(Competitor::Sex const newSex) this->sex = newSex; } +QString const &Competitor::getClub() const +{ + return club; +} + +QString Competitor::getClub(int newWidth) const +{ + return QString("%1").arg(this->club, -newWidth); +} + +void Competitor::setClub(QString const &newClub) +{ + this->club = newClub; +} + +void Competitor::setClub(QString const *newClub) +{ + if (newClub) + this->club = *newClub; +} + QString const &Competitor::getTeam() const { return team; @@ -301,6 +326,8 @@ bool CompetitorSorter::operator() (Competitor const &lhs, Competitor const &rhs) return (sortingOrder == Qt::DescendingOrder) ? (Competitor::toSexString(lhs.getSex()) > Competitor::toSexString(rhs.getSex())) : (Competitor::toSexString(lhs.getSex()) < Competitor::toSexString(rhs.getSex())); case Competitor::Field::CMF_YEAR: return (sortingOrder == Qt::DescendingOrder) ? (lhs.getYear() > rhs.getYear()) : (lhs.getYear() < rhs.getYear()); + case Competitor::Field::CMF_CLUB: + return (sortingOrder == Qt::DescendingOrder) ? (lhs.getClub() > rhs.getClub()) : (lhs.getClub() < rhs.getClub()); case Competitor::Field::CMF_TEAM: return (sortingOrder == Qt::DescendingOrder) ? (lhs.getTeam() > rhs.getTeam()) : (lhs.getTeam() < rhs.getTeam()); case Competitor::Field::CMF_BIB: diff --git a/competitor.hpp b/competitor.hpp index 95afdbf..58e1b9f 100644 --- a/competitor.hpp +++ b/competitor.hpp @@ -47,10 +47,11 @@ class Competitor CMF_NAME = 1, CMF_SEX = 2, CMF_YEAR = 3, - CMF_TEAM = 4, - CMF_OFFSET_LEG = 5, - CMF_LAST = 5, - CMF_COUNT = 6 + CMF_CLUB = 4, + CMF_TEAM = 5, + CMF_OFFSET_LEG = 6, + CMF_LAST = 6, + CMF_COUNT = 7 }; private: @@ -59,6 +60,7 @@ class Competitor QString name { "" }; Sex sex { Sex::UNDEFINED }; uint year { 1900 }; + QString club { "" }; QString team { "" }; uint leg { 1u }; int offset { -1 }; @@ -78,6 +80,10 @@ class Competitor void setBib(uint newBib); Sex getSex() const; void setSex(Sex const newSex); + QString const &getClub() const; + QString getClub(int newWidth) const; + void setClub(QString const &newClub); + void setClub(QString const *newClub); QString const &getTeam() const; QString getTeam(int newWidth) const; void setTeam(QString const &newTeam); diff --git a/crloader.cpp b/crloader.cpp index bcfcfad..73fc166 100644 --- a/crloader.cpp +++ b/crloader.cpp @@ -253,12 +253,12 @@ uint CRLoader::getStartListBibMax() uint CRLoader::getStartListNameWidthMax() { - return startListModel.getCompetitorNameMaxWidth(); + return startListModel.getCompetitorNameWidthMax(); } uint CRLoader::getTeamNameWidthMax() { - return teamsListModel.getTeamNameWidthMax(); + return startListModel.getTeamNameWidthMax(); } int CRLoader::importTimings(QString const &path) diff --git a/csvrankingprinter.cpp b/csvrankingprinter.cpp index a5fed8a..fc0cb67 100644 --- a/csvrankingprinter.cpp +++ b/csvrankingprinter.cpp @@ -97,16 +97,16 @@ void CSVRankingPrinter::printRanking(const Category &category, QListgetTotalTimeTxt(); + currTime = c->getTotalTime(CRLoader::Format::CSV); if ((currPosNumber = position.getCurrentPositionNumber(i, currTime)) == 0) currPosNumber = prevPosNumber; else prevPosNumber = currPosNumber; csvStream << currPosNumber << ","; csvStream << c->getBib() << ","; - csvStream << c->getNamesCSV() << ","; + csvStream << c->getNames(CRLoader::Format::CSV) << ","; if (CRLoader::getStartListLegs() > 1) - csvStream << c->getTimesCSV() << ","; + csvStream << c->getTimes(CRLoader::Format::CSV) << ","; csvStream << currTime << Qt::endl; } csvStream << Qt::endl; @@ -125,10 +125,10 @@ void CSVRankingPrinter::printRanking(const Category &category, QListgetClassEntryCount(); j++) { csvStream << i << ","; csvStream << r->getClassEntry(j)->getBib() << ","; - csvStream << r->getClassEntry(j)->getNamesCSV() << ","; + csvStream << r->getClassEntry(j)->getNames(CRLoader::Format::CSV) << ","; if (CRLoader::getStartListLegs() > 1) - csvStream << r->getClassEntry(j)->getTimesCSV() << ","; - csvStream << r->getClassEntry(j)->getTotalTimeCSV() << Qt::endl; + csvStream << r->getClassEntry(j)->getTimes(CRLoader::Format::CSV) << ","; + csvStream << r->getClassEntry(j)->getTotalTime(CRLoader::Format::CSV) << Qt::endl; } } csvStream << Qt::endl; diff --git a/lbchronorace.cpp b/lbchronorace.cpp index a34c309..649e63b 100644 --- a/lbchronorace.cpp +++ b/lbchronorace.cpp @@ -33,6 +33,7 @@ // static members initialization QDir LBChronoRace::lastSelectedPath(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)); +int LBChronoRace::binFormat = LBCHRONORACE_BIN_FMT; LBChronoRace::LBChronoRace(QWidget *parent, QGuiApplication const *app) : QMainWindow(parent), @@ -56,14 +57,14 @@ LBChronoRace::LBChronoRace(QWidget *parent, QGuiApplication const *app) : QObject::connect(&startListTable, &ChronoRaceTable::newRowCount, this, &LBChronoRace::setCounterCompetitors); teamsTable.disableButtons(); - teamsTable.setWindowTitle(tr("Teams List")); + teamsTable.setWindowTitle(tr("Clubs List")); teamsTable.setModel(CRLoader::getTeamsListModel()); QObject::connect(&teamsTable, &ChronoRaceTable::modelExported, this, &LBChronoRace::exportTeamList); QObject::connect(&teamsTable, &ChronoRaceTable::newRowCount, this, &LBChronoRace::setCounterTeams); auto const *startListModel = (StartListModel const *) CRLoader::getStartListModel(); auto const *teamsListModel = (TeamsListModel const *) CRLoader::getTeamsListModel(); - QObject::connect(startListModel, &StartListModel::newTeam, teamsListModel, &TeamsListModel::addTeam); + QObject::connect(startListModel, &StartListModel::newClub, teamsListModel, &TeamsListModel::addTeam); QObject::connect(startListModel, &StartListModel::error, this, &LBChronoRace::appendErrorMessage); auto *categoriesModel = (CategoriesModel *) CRLoader::getCategoriesModel(); @@ -95,7 +96,7 @@ LBChronoRace::LBChronoRace(QWidget *parent, QGuiApplication const *app) : QObject::connect(ui->saveRace, &QPushButton::clicked, this, &LBChronoRace::saveRace); QObject::connect(ui->editRace, &QPushButton::clicked, &raceInfo, &ChronoRaceData::show); QObject::connect(ui->editStartList, &QPushButton::clicked, &startListTable, &ChronoRaceTable::show); - QObject::connect(ui->editTeamsList, &QPushButton::clicked, &teamsTable, &ChronoRaceTable::show); + QObject::connect(ui->editClubsList, &QPushButton::clicked, &teamsTable, &ChronoRaceTable::show); QObject::connect(ui->editCategories, &QPushButton::clicked, &categoriesTable, &ChronoRaceTable::show); QObject::connect(ui->editTimings, &QPushButton::clicked, &timingsTable, &ChronoRaceTable::show); QObject::connect(ui->makeStartList, &QPushButton::clicked, this, &LBChronoRace::makeStartList); @@ -230,7 +231,7 @@ void LBChronoRace::exportStartList() void LBChronoRace::exportTeamList() { - teamsFileName = QFileDialog::getSaveFileName(this, tr("Select Teams List"), + teamsFileName = QFileDialog::getSaveFileName(this, tr("Select Clubs List"), lastSelectedPath.absolutePath(), tr("CSV (*.csv)")); if (!teamsFileName.isEmpty()) { @@ -378,11 +379,14 @@ bool LBChronoRace::loadRaceFile(QString const &fileName) switch (binFmt) { case LBCHRONORACE_BIN_FMT_v1: case LBCHRONORACE_BIN_FMT_v2: + case LBCHRONORACE_BIN_FMT_v3: QAbstractTableModel const *table; qint16 encodingIdx; qint16 formatIdx; int tableCount; + binFormat = static_cast(binFmt); + in >> encodingIdx; encodingSelector(encodingIdx); in >> formatIdx; diff --git a/lbchronorace.hpp b/lbchronorace.hpp index f69cc6a..7b5d64f 100644 --- a/lbchronorace.hpp +++ b/lbchronorace.hpp @@ -43,7 +43,8 @@ constexpr char LBCHRONORACE_CATEGORIES_DEFAULT[] = "categories.csv"; constexpr int LBCHRONORACE_BIN_FMT_v1 = 1; constexpr int LBCHRONORACE_BIN_FMT_v2 = 2; -#define LBCHRONORACE_BIN_FMT LBCHRONORACE_BIN_FMT_v2 +constexpr int LBCHRONORACE_BIN_FMT_v3 = 3; +#define LBCHRONORACE_BIN_FMT LBCHRONORACE_BIN_FMT_v3 class LBChronoRace : public QMainWindow { @@ -53,6 +54,7 @@ class LBChronoRace : public QMainWindow explicit LBChronoRace(QWidget *parent = Q_NULLPTR, QGuiApplication const *app = Q_NULLPTR); static QDir lastSelectedPath; + static int binFormat; public slots: void initialize(); diff --git a/pdfrankingprinter.cpp b/pdfrankingprinter.cpp index 4b16174..b3eec25 100644 --- a/pdfrankingprinter.cpp +++ b/pdfrankingprinter.cpp @@ -154,7 +154,7 @@ void PDFRankingPrinter::printStartList(QList const &startList) painter.setFont(rnkFont); writeRect.translate(toHdots(60.0), 0.0); writeRect.setWidth(toHdots(45.0)); - painter.drawText(writeRect.toRect(), Qt::AlignLeft | Qt::AlignVCenter, (*c)->getTeam()); + painter.drawText(writeRect.toRect(), Qt::AlignLeft | Qt::AlignVCenter, (*c)->getClub() + " " + (*c)->getTeam()); // Year writeRect.translate(toHdots(45.0), 0.0); writeRect.setWidth(toHdots(9.0)); @@ -638,7 +638,7 @@ void PDFRankingPrinter::printEntrySingleLeg(QRectF &writeRect, ClassEntry const { static Position position; - QString currTime = c->getTotalTimeTxt(); + QString currTime = c->getTotalTime(CRLoader::Format::PDF); switch (type) { case RankingType::INDIVIDUAL_SINGLE: @@ -685,7 +685,7 @@ void PDFRankingPrinter::printEntrySingleLeg(QRectF &writeRect, ClassEntry const painter.setFont(rnkFont); writeRect.translate(toHdots(60.0), 0.0); writeRect.setWidth(toHdots(45.0)); - painter.drawText(writeRect.toRect(), Qt::AlignLeft | Qt::AlignVCenter, c->getTeam()); + painter.drawText(writeRect.toRect(), Qt::AlignLeft | Qt::AlignVCenter, c->getClub() + " " + c->getTeam()); // Year writeRect.translate(toHdots(45.0), 0.0); writeRect.setWidth(toHdots(9.0)); @@ -753,7 +753,7 @@ void PDFRankingPrinter::printEntryMultiLeg(QRectF &writeRect, ClassEntry const * auto entriesPerBlock = static_cast(CRLoader::getStartListLegs() + 1); - QString currTime = r->getTotalTimeTxt(); + QString currTime = r->getTotalTime(CRLoader::Format::PDF); switch (type) { case RankingType::INDIVIDUAL_MULTI: @@ -797,7 +797,7 @@ void PDFRankingPrinter::printEntryMultiLeg(QRectF &writeRect, ClassEntry const * painter.setFont(rnkFontBold); writeRect.translate(toHdots(8.0), 0.0); writeRect.setWidth(toHdots(66.0)); - painter.drawText(writeRect.toRect(), Qt::AlignLeft | Qt::AlignVCenter, r->getTeam()); + painter.drawText(writeRect.toRect(), Qt::AlignLeft | Qt::AlignVCenter, r->getClub() + " " + r->getTeam()); // Category painter.setFont(rnkFont); writeRect.translate(toHdots(66.0), 0.0); diff --git a/rankingsbuilder.cpp b/rankingsbuilder.cpp index 35254cb..b9e9d59 100644 --- a/rankingsbuilder.cpp +++ b/rankingsbuilder.cpp @@ -167,8 +167,8 @@ QList &RankingsBuilder::fillRanking(QListgetTeam().isEmpty()) { + // exclude competitors without club + if (classEntry->getClub().isEmpty()) { continue; } @@ -190,11 +190,11 @@ QList &RankingsBuilder::fillRanking(QListgetTeam(); + QString const &club = classEntry->getClub(); - QMap::iterator const teamRankingIt = rankingByTeam.find(team); + QMap::iterator const teamRankingIt = rankingByTeam.find(club); if (teamRankingIt == rankingByTeam.end()) { - rankingByTeam.insert(team, TeamClassEntry()).value().setClassEntry(classEntry); + rankingByTeam.insert(club, TeamClassEntry()).value().setClassEntry(classEntry); } else { teamRankingIt.value().setClassEntry(classEntry); } diff --git a/samples/mass_start/latin1/startlist.csv b/samples/mass_start/latin1/startlist.csv index 1aac0b2..2660480 100644 --- a/samples/mass_start/latin1/startlist.csv +++ b/samples/mass_start/latin1/startlist.csv @@ -1,187 +1,187 @@ -1,GONZALO MONROIG,M,1970,TEAM A,1 -2,LEOPOLDO LINDSAY,M,1973,TEAM A,1 -3,ERNIE GENTILE,M,1988,TEAM B,1 -4,GARTH HEATHERINGTON,M,1964,TEAM C,1 -5,LOYD GAMET,M,1965,TEAM D,1 -6,JACINTO NIPP,M,1957,TEAM E,1 -7,LEONARDO QUILES,M,1964,TEAM E,1 -8,COLE NESTER,M,1955,TEAM F,1 -9,EMILIO AGENA,M,1974,TEAM D,1 -10,ALBA BUSHARD,F,1976,TEAM D,1 -11,SERGIO FULCHER,M,1984,TEAM G,1 -12,DARELL LAFONTANT,M,1992,TEAM C,1 -13,MINERVA LEVEY,F,1967,TEAM H,1 -14,ARNULFO SPROUL,M,1959,TEAM I,1 -15,LAVERA GUIDOTTI,F,1963,TEAM I,1 -16,NATACHA DUROCHER,F,1965,TEAM E,1 -17,ANGLEA GAGE,F,1954,TEAM E,1 -18,JOSE ZALEWSKI,M,1965,TEAM C,1 -19,BOBBIE WILTSE,M,1961,TEAM A,1 -20,YEE HEDLEY,F,1971,TEAM C,1 -21,CHI CAULEY,M,1960,TEAM I,1 -22,BRUNO CROKE,M,1968,TEAM I,1 -23,LEONEL TEETER,M,1968,TEAM A,1 -24,GAVIN KOVACICH,M,1971,TEAM A,1 -25,LESTER LUCERO,M,1981,TEAM J,1 -26,MINA NIMS,F,1966,TEAM I,1 -27,TOBIE RINEY,F,1967,TEAM K,1 -28,VANETTA BECKMANN,F,1960,TEAM I,1 -29,TREVOR READY,M,1958,TEAM L,1 -30,ELOISE MANISCALCO,F,1965,TEAM K,1 -31,BERT HOOS,M,1980,TEAM M,1 -32,BRIAN STAHL,M,1954,TEAM N,1 -33,BILLY BOLTEN,M,1973,TEAM N,1 -34,IVAN MAGWOOD,M,1972,TEAM K,1 -35,FAUSTINO RESTREPO,M,1972,TEAM O,1 -36,SHANICE RALEIGH,F,1975,TEAM I,1 -37,ERIC RAYA,M,1975,TEAM C,1 -38,ADELE LANSBERRY,F,1966,TEAM P,1 -39,RALEIGH WESSELS,M,1981,TEAM Q,1 -40,PEDRO VELIZ,M,1964,TEAM R,1 -41,RANEE MIDGETT,F,1966,TEAM I,1 -42,CLINT BOETTCHER,M,1965,TEAM I,1 -43,IRVIN SHIVELY,M,1968,TEAM D,1 -44,SUNNI GOTTLIEB,F,1969,TEAM R,1 -45,ELLIOTT CHESHIRE,M,1969,TEAM R,1 -46,OMER MCCALLISTER,M,1976,TEAM S,1 -47,TIFFANEY HUBLER,F,1965,TEAM J,1 -48,ASHLEY DAIGNEAULT,M,1971,TEAM O,1 -49,ELIAS QUISENBERRY,M,1964,TEAM T,1 -50,RODGER MOLINAR,M,1970,TEAM U,1 -51,CRUZ TOPE,M,1964,TEAM R,1 -52,BOBBY ARCAND,M,1974,TEAM A,1 -53,ENOCH ENYEART,M,1989,TEAM V,1 -54,BRET CRASS,M,1973,TEAM T,1 -55,MOISES ARCURI,M,1969,TEAM A,1 -56,KIETH STICH,M,1985,TEAM A,1 -57,TASHINA DESCHAINE,F,1973,TEAM A,1 -58,DEVIN LANGSTON,M,1964,TEAM W,1 -59,ALVA CLEVER,M,1973,TEAM A,1 -60,ANTIONE GOVER,M,1959,TEAM X,1 -61,HENRIETTA RICARD,F,1965,TEAM X,1 -98,CARINA HIEB,F,1980,TEAM A,1 -101,AUGUSTUS MAILLOUX,M,1963,TEAM W,1 -102,OTTO FAUNCE,M,1972,TEAM C,1 -104,NOLAN STALTER,M,1964,TEAM B,1 -105,ANIKA AMEZCUA,F,1967,TEAM B,1 -106,ALEXIS MOREFIELD,M,1999,TEAM J,1 -107,KURTIS TWOMEY,M,1976,TEAM Y,1 -108,PARIS LINSLEY,M,1972,TEAM Y,1 -109,SEAN GARTON,M,1994,TEAM S,1 -110,IGNACIO OHERN,M,1996,TEAM Z,1 -112,ANTHONY ARBEITER,M,1959,TEAM B,1 -113,MARC LUEBBERT,M,1987,TEAM O,1 -114,ZENOBIA GRINDER,F,1965,---,1 -115,JOSIAH SABADO,M,1976,TEAM B,1 -116,ELIZABET SHEARER,F,1996,TEAM Y,1 -117,SCOTTY FRITZLER,M,1962,TEAM J,1 -118,TEODORO TOWN,M,1972,TEAM J,1 -119,KRISTA DANIEL,F,1985,TEAM J,1 -120,LUTHER DRYER,M,1973,TEAM J,1 -121,JAE VEASLEY,M,1980,TEAM J,1 -122,MAURICIO RODRIQUES,M,1953,TEAM J,1 -123,LOUISA NOYES,F,1951,TEAM I,1 -124,BRANDA MOOS,F,1966,TEAM I,1 -125,CATRINA CURLIN,F,1971,TEAM I,1 -126,MACK ELSWORTH,M,1969,TEAM A,1 -127,GORDON PURVINES,M,1971,TEAM 1,1 -128,KARRIE MANDELL,F,1946,TEAM 2,1 -129,REED EASTER,M,1947,TEAM 2,1 -130,VEDA SHANKS,F,1979,TEAM K,1 -131,LINDSEY WISNESKI,M,1974,TEAM U,1 -132,FREDERICK GONSALVES,M,1971,TEAM R,1 -133,WINFRED YANG,M,1951,TEAM 3,1 -134,SAMMY TORRANCE,M,1972,TEAM A,1 -135,ARRON BONDY,M,1984,TEAM 4,1 -136,GRACIA KWOK,F,1971,TEAM 1,1 -137,MONTE PAGAN,M,1957,TEAM A,1 -138,ORVILLE KREBSBACH,M,1970,TEAM D,1 -139,ELINOR SENGER,F,1974,TEAM I,1 -140,OCTAVIO CARDELLO,M,1975,TEAM B,1 -141,ARCHIE HERNANDEZ,M,1971,TEAM B,1 -142,GENNY BRIAN,F,1975,TEAM R,1 -143,MIGNON HADSELL,F,1974,TEAM T,1 -144,JORDAN COBLE,M,1958,TEAM 5,1 -145,DARRYL ROSSIN,M,1967,TEAM P,1 -146,EMILIE TRIGGS,F,1979,TEAM C,1 -147,ALI GIRALDO,M,1969,TEAM A,1 -148,QUYEN STENBERG,F,1975,TEAM 6,1 -149,CHAS HUBBELL,M,1975,TEAM 6,1 -150,HANK EFFINGER,M,1981,TEAM J,1 -151,TERRESA DAWDY,F,1959,TEAM I,1 -152,ERA CROLL,F,1969,TEAM I,1 -153,BENJAMIN ADOLPHSEN,M,1945,TEAM 7,1 -154,LEIGHA THORMAN,F,1965,---,1 -155,CLEO HELBERG,M,1962,---,1 -156,DIANNE HARDAGE,F,1965,TEAM R,1 -157,CRIS ZACARIAS,F,1972,TEAM R,1 -158,ERNA FERBER,F,1970,TEAM R,1 -159,JED TEWELL,M,1976,TEAM I,1 -160,DESMOND FORTENBERRY,M,1983,TEAM A,1 -201,ABRAHAM CROCE,M,1980,TEAM A,1 -202,MASON BITTNER,M,1996,TEAM B,1 -203,RUSSEL SUHR,M,1973,TEAM 1,1 -204,BRYANT PLOURDE,M,1974,TEAM 1,1 -205,WERNER PEREA,M,1956,TEAM D,1 -206,CASEY WILLMS,M,1957,TEAM D,1 -207,GENARO LO,M,1961,TEAM D,1 -208,DONNY MCCANE,M,1958,TEAM T,1 -209,EDGARDO ALVARENGA,M,1951,TEAM D,1 -210,RAYMON MORADO,M,1957,TEAM G,1 -211,AURELIO PERRELLA,M,1954,TEAM 8,1 -212,CYRIL MORRIS,M,1956,TEAM 2,1 -213,WALTER HARTZOG,M,1967,TEAM 9,1 -214,CHAD CARRIZALES,M,1670,TEAM 9,1 -215,COLUMBUS BUTTON,M,1964,TEAM 10,1 -216,TOI DEDIOS,F,1962,TEAM I,1 -217,LEO DILLE,M,1967,TEAM B,1 -218,LYDA RAWLINS,F,1979,TEAM C,1 -219,JERRELL PISCITELLI,M,1979,TEAM T,1 -220,KAZUKO PURDUE,F,1971,TEAM I,1 -221,SHANTELL MCGOWIN,F,1973,TEAM A,1 -222,TODD DOKE,M,1971,TEAM J,1 -223,MARCY FORTINO,F,1961,TEAM J,1 -224,HAL KAUFFMAN,M,1959,TEAM K,1 -225,HEATH LANGSAM,M,1968,TEAM D,1 -226,ALBERT ABERLE,M,1966,TEAM K,1 -227,ELI AMAR,M,1971,TEAM C,1 -228,BRETT HARGETT,M,1964,TEAM A,1 -229,THERON RIGG,M,1988,TEAM 6,1 -230,SEYMOUR HERSEY,M,1980,TEAM 6,1 -231,JOSHUA HOWERTON,M,1967,TEAM 3,1 -232,HARLEY BRANDENBURG,M,1982,TEAM V,1 -233,DOMINGA MCNEELY,F,1974,TEAM B,1 -234,WILFRED BERNAL,M,1969,TEAM B,1 -235,CALVIN STANWOOD,M,1958,TEAM I,1 -236,JEFF HUCK,M,1960,TEAM P,1 -237,LANNY SWICK,M,1971,TEAM C,1 -238,JONAS MINNIFIELD,M,1986,TEAM F,1 -239,TOBIAS MATIAS,M,1975,TEAM A,1 -240,RHETT ROSENGARTEN,M,1952,TEAM F,1 -241,ROXANNA MELGAREJO,F,1973,TEAM I,1 -242,REUBEN DELBOSQUE,M,1971,I.A.A.F.,1 -243,MYRON SIMEON,M,1969,I.A.A.F.,1 -244,GLAYDS BIONDO,F,1973,TEAM 11,1 -245,FILIBERTO DUNMIRE,M,1984,TEAM 11,1 -246,SHERWOOD EMORY,M,1977,TEAM 11,1 -247,LUCIUS CAUSEY,M,1994,TEAM I,1 -248,THURMAN WETTER,M,1976,TEAM B,1 -249,LORE CROWE,F,1980,TEAM 1,1 -250,JESUS BRADISH,M,1976,TEAM G,1 -251,HAROLD FICKLIN,M,1980,TEAM 12,1 -252,PHIL HALBROOK,M,1985,TEAM 1,1 -253,MAIRA PAINTER,F,1974,TEAM R,1 -255,GARRET ASHBURN,M,1978,TEAM R,1 -256,KASEY CANCEL,M,1978,TEAM R,1 -257,AVA SIEVERS,F,1981,TEAM R,1 -258,RICK HICKS,M,1965,TEAM U,1 -259,LEWIS FORRY,M,1964,TEAM I,1 -260,RUBIN MCBRYDE,M,1966,TEAM C,1 -261,KAI POZO,F,1996,TEAM Z,1 -262,ROLF COUTURIER,M,1980,TEAM I,1 -263,TRENA KESTEN,F,1990,TEAM W,1 -264,WILFREDO GENGLER,M,1971,TEAM 11,1 -265,GIUSEPPE HASSEN,M,1954,TEAM 13,1 -266,ARMANDINA TOOHEY,F,1979,TEAM I,1 -267,GUILLERMO HUNGER,M,1976,TEAM I,1 -268,CHONG EHLERT,M,1963,TEAM A,1 +1,GONZALO MONROIG,M,1970,TEAM A,,1 +2,LEOPOLDO LINDSAY,M,1973,TEAM A,,1 +3,ERNIE GENTILE,M,1988,TEAM B,,1 +4,GARTH HEATHERINGTON,M,1964,TEAM C,,1 +5,LOYD GAMET,M,1965,TEAM D,,1 +6,JACINTO NIPP,M,1957,TEAM E,,1 +7,LEONARDO QUILES,M,1964,TEAM E,,1 +8,COLE NESTER,M,1955,TEAM F,,1 +9,EMILIO AGENA,M,1974,TEAM D,,1 +10,ALBA BUSHARD,F,1976,TEAM D,,1 +11,SERGIO FULCHER,M,1984,TEAM G,,1 +12,DARELL LAFONTANT,M,1992,TEAM C,,1 +13,MINERVA LEVEY,F,1967,TEAM H,,1 +14,ARNULFO SPROUL,M,1959,TEAM I,,1 +15,LAVERA GUIDOTTI,F,1963,TEAM I,,1 +16,NATACHA DUROCHER,F,1965,TEAM E,,1 +17,ANGLEA GAGE,F,1954,TEAM E,,1 +18,JOSE ZALEWSKI,M,1965,TEAM C,,1 +19,BOBBIE WILTSE,M,1961,TEAM A,,1 +20,YEE HEDLEY,F,1971,TEAM C,,1 +21,CHI CAULEY,M,1960,TEAM I,,1 +22,BRUNO CROKE,M,1968,TEAM I,,1 +23,LEONEL TEETER,M,1968,TEAM A,,1 +24,GAVIN KOVACICH,M,1971,TEAM A,,1 +25,LESTER LUCERO,M,1981,TEAM J,,1 +26,MINA NIMS,F,1966,TEAM I,,1 +27,TOBIE RINEY,F,1967,TEAM K,,1 +28,VANETTA BECKMANN,F,1960,TEAM I,,1 +29,TREVOR READY,M,1958,TEAM L,,1 +30,ELOISE MANISCALCO,F,1965,TEAM K,,1 +31,BERT HOOS,M,1980,TEAM M,,1 +32,BRIAN STAHL,M,1954,TEAM N,,1 +33,BILLY BOLTEN,M,1973,TEAM N,,1 +34,IVAN MAGWOOD,M,1972,TEAM K,,1 +35,FAUSTINO RESTREPO,M,1972,TEAM O,,1 +36,SHANICE RALEIGH,F,1975,TEAM I,,1 +37,ERIC RAYA,M,1975,TEAM C,,1 +38,ADELE LANSBERRY,F,1966,TEAM P,,1 +39,RALEIGH WESSELS,M,1981,TEAM Q,,1 +40,PEDRO VELIZ,M,1964,TEAM R,,1 +41,RANEE MIDGETT,F,1966,TEAM I,,1 +42,CLINT BOETTCHER,M,1965,TEAM I,,1 +43,IRVIN SHIVELY,M,1968,TEAM D,,1 +44,SUNNI GOTTLIEB,F,1969,TEAM R,,1 +45,ELLIOTT CHESHIRE,M,1969,TEAM R,,1 +46,OMER MCCALLISTER,M,1976,TEAM S,,1 +47,TIFFANEY HUBLER,F,1965,TEAM J,,1 +48,ASHLEY DAIGNEAULT,M,1971,TEAM O,,1 +49,ELIAS QUISENBERRY,M,1964,TEAM T,,1 +50,RODGER MOLINAR,M,1970,TEAM U,,1 +51,CRUZ TOPE,M,1964,TEAM R,,1 +52,BOBBY ARCAND,M,1974,TEAM A,,1 +53,ENOCH ENYEART,M,1989,TEAM V,,1 +54,BRET CRASS,M,1973,TEAM T,,1 +55,MOISES ARCURI,M,1969,TEAM A,,1 +56,KIETH STICH,M,1985,TEAM A,,1 +57,TASHINA DESCHAINE,F,1973,TEAM A,,1 +58,DEVIN LANGSTON,M,1964,TEAM W,,1 +59,ALVA CLEVER,M,1973,TEAM A,,1 +60,ANTIONE GOVER,M,1959,TEAM X,,1 +61,HENRIETTA RICARD,F,1965,TEAM X,,1 +98,CARINA HIEB,F,1980,TEAM A,,1 +101,AUGUSTUS MAILLOUX,M,1963,TEAM W,,1 +102,OTTO FAUNCE,M,1972,TEAM C,,1 +104,NOLAN STALTER,M,1964,TEAM B,,1 +105,ANIKA AMEZCUA,F,1967,TEAM B,,1 +106,ALEXIS MOREFIELD,M,1999,TEAM J,,1 +107,KURTIS TWOMEY,M,1976,TEAM Y,,1 +108,PARIS LINSLEY,M,1972,TEAM Y,,1 +109,SEAN GARTON,M,1994,TEAM S,,1 +110,IGNACIO OHERN,M,1996,TEAM Z,,1 +112,ANTHONY ARBEITER,M,1959,TEAM B,,1 +113,MARC LUEBBERT,M,1987,TEAM O,,1 +114,ZENOBIA GRINDER,F,1965,---,,1 +115,JOSIAH SABADO,M,1976,TEAM B,,1 +116,ELIZABET SHEARER,F,1996,TEAM Y,,1 +117,SCOTTY FRITZLER,M,1962,TEAM J,,1 +118,TEODORO TOWN,M,1972,TEAM J,,1 +119,KRISTA DANIEL,F,1985,TEAM J,,1 +120,LUTHER DRYER,M,1973,TEAM J,,1 +121,JAE VEASLEY,M,1980,TEAM J,,1 +122,MAURICIO RODRIQUES,M,1953,TEAM J,,1 +123,LOUISA NOYES,F,1951,TEAM I,,1 +124,BRANDA MOOS,F,1966,TEAM I,,1 +125,CATRINA CURLIN,F,1971,TEAM I,,1 +126,MACK ELSWORTH,M,1969,TEAM A,,1 +127,GORDON PURVINES,M,1971,TEAM 1,,1 +128,KARRIE MANDELL,F,1946,TEAM 2,,1 +129,REED EASTER,M,1947,TEAM 2,,1 +130,VEDA SHANKS,F,1979,TEAM K,,1 +131,LINDSEY WISNESKI,M,1974,TEAM U,,1 +132,FREDERICK GONSALVES,M,1971,TEAM R,,1 +133,WINFRED YANG,M,1951,TEAM 3,,1 +134,SAMMY TORRANCE,M,1972,TEAM A,,1 +135,ARRON BONDY,M,1984,TEAM 4,,1 +136,GRACIA KWOK,F,1971,TEAM 1,,1 +137,MONTE PAGAN,M,1957,TEAM A,,1 +138,ORVILLE KREBSBACH,M,1970,TEAM D,,1 +139,ELINOR SENGER,F,1974,TEAM I,,1 +140,OCTAVIO CARDELLO,M,1975,TEAM B,,1 +141,ARCHIE HERNANDEZ,M,1971,TEAM B,,1 +142,GENNY BRIAN,F,1975,TEAM R,,1 +143,MIGNON HADSELL,F,1974,TEAM T,,1 +144,JORDAN COBLE,M,1958,TEAM 5,,1 +145,DARRYL ROSSIN,M,1967,TEAM P,,1 +146,EMILIE TRIGGS,F,1979,TEAM C,,1 +147,ALI GIRALDO,M,1969,TEAM A,,1 +148,QUYEN STENBERG,F,1975,TEAM 6,,1 +149,CHAS HUBBELL,M,1975,TEAM 6,,1 +150,HANK EFFINGER,M,1981,TEAM J,,1 +151,TERRESA DAWDY,F,1959,TEAM I,,1 +152,ERA CROLL,F,1969,TEAM I,,1 +153,BENJAMIN ADOLPHSEN,M,1945,TEAM 7,,1 +154,LEIGHA THORMAN,F,1965,---,,1 +155,CLEO HELBERG,M,1962,---,,1 +156,DIANNE HARDAGE,F,1965,TEAM R,,1 +157,CRIS ZACARIAS,F,1972,TEAM R,,1 +158,ERNA FERBER,F,1970,TEAM R,,1 +159,JED TEWELL,M,1976,TEAM I,,1 +160,DESMOND FORTENBERRY,M,1983,TEAM A,,1 +201,ABRAHAM CROCE,M,1980,TEAM A,,1 +202,MASON BITTNER,M,1996,TEAM B,,1 +203,RUSSEL SUHR,M,1973,TEAM 1,,1 +204,BRYANT PLOURDE,M,1974,TEAM 1,,1 +205,WERNER PEREA,M,1956,TEAM D,,1 +206,CASEY WILLMS,M,1957,TEAM D,,1 +207,GENARO LO,M,1961,TEAM D,,1 +208,DONNY MCCANE,M,1958,TEAM T,,1 +209,EDGARDO ALVARENGA,M,1951,TEAM D,,1 +210,RAYMON MORADO,M,1957,TEAM G,,1 +211,AURELIO PERRELLA,M,1954,TEAM 8,,1 +212,CYRIL MORRIS,M,1956,TEAM 2,,1 +213,WALTER HARTZOG,M,1967,TEAM 9,,1 +214,CHAD CARRIZALES,M,1670,TEAM 9,,1 +215,COLUMBUS BUTTON,M,1964,TEAM 10,,1 +216,TOI DEDIOS,F,1962,TEAM I,,1 +217,LEO DILLE,M,1967,TEAM B,,1 +218,LYDA RAWLINS,F,1979,TEAM C,,1 +219,JERRELL PISCITELLI,M,1979,TEAM T,,1 +220,KAZUKO PURDUE,F,1971,TEAM I,,1 +221,SHANTELL MCGOWIN,F,1973,TEAM A,,1 +222,TODD DOKE,M,1971,TEAM J,,1 +223,MARCY FORTINO,F,1961,TEAM J,,1 +224,HAL KAUFFMAN,M,1959,TEAM K,,1 +225,HEATH LANGSAM,M,1968,TEAM D,,1 +226,ALBERT ABERLE,M,1966,TEAM K,,1 +227,ELI AMAR,M,1971,TEAM C,,1 +228,BRETT HARGETT,M,1964,TEAM A,,1 +229,THERON RIGG,M,1988,TEAM 6,,1 +230,SEYMOUR HERSEY,M,1980,TEAM 6,,1 +231,JOSHUA HOWERTON,M,1967,TEAM 3,,1 +232,HARLEY BRANDENBURG,M,1982,TEAM V,,1 +233,DOMINGA MCNEELY,F,1974,TEAM B,,1 +234,WILFRED BERNAL,M,1969,TEAM B,,1 +235,CALVIN STANWOOD,M,1958,TEAM I,,1 +236,JEFF HUCK,M,1960,TEAM P,,1 +237,LANNY SWICK,M,1971,TEAM C,,1 +238,JONAS MINNIFIELD,M,1986,TEAM F,,1 +239,TOBIAS MATIAS,M,1975,TEAM A,,1 +240,RHETT ROSENGARTEN,M,1952,TEAM F,,1 +241,ROXANNA MELGAREJO,F,1973,TEAM I,,1 +242,REUBEN DELBOSQUE,M,1971,I.A.A.F.,,1 +243,MYRON SIMEON,M,1969,I.A.A.F.,,1 +244,GLAYDS BIONDO,F,1973,TEAM 11,,1 +245,FILIBERTO DUNMIRE,M,1984,TEAM 11,,1 +246,SHERWOOD EMORY,M,1977,TEAM 11,,1 +247,LUCIUS CAUSEY,M,1994,TEAM I,,1 +248,THURMAN WETTER,M,1976,TEAM B,,1 +249,LORE CROWE,F,1980,TEAM 1,,1 +250,JESUS BRADISH,M,1976,TEAM G,,1 +251,HAROLD FICKLIN,M,1980,TEAM 12,,1 +252,PHIL HALBROOK,M,1985,TEAM 1,,1 +253,MAIRA PAINTER,F,1974,TEAM R,,1 +255,GARRET ASHBURN,M,1978,TEAM R,,1 +256,KASEY CANCEL,M,1978,TEAM R,,1 +257,AVA SIEVERS,F,1981,TEAM R,,1 +258,RICK HICKS,M,1965,TEAM U,,1 +259,LEWIS FORRY,M,1964,TEAM I,,1 +260,RUBIN MCBRYDE,M,1966,TEAM C,,1 +261,KAI POZO,F,1996,TEAM Z,,1 +262,ROLF COUTURIER,M,1980,TEAM I,,1 +263,TRENA KESTEN,F,1990,TEAM W,,1 +264,WILFREDO GENGLER,M,1971,TEAM 11,,1 +265,GIUSEPPE HASSEN,M,1954,TEAM 13,,1 +266,ARMANDINA TOOHEY,F,1979,TEAM I,,1 +267,GUILLERMO HUNGER,M,1976,TEAM I,,1 +268,CHONG EHLERT,M,1963,TEAM A,,1 diff --git a/samples/mass_start/mass_start.crd b/samples/mass_start/mass_start.crd index 64e2ab5372abe2ff1ebfa11ea0a115653e175eba..ddc9fc24cd48c3b474c4b077a78d20a2543438b1 100644 GIT binary patch delta 2058 zcmYk7Ur1A77{-t5Yt`}#DJzH&@j@cHhzgR3kP$ZYzlqN1a7&biHb zrgNswIp>`7-=_VM5a}XBypjlsh=}MaM7rq8I(7VgbYRbg^F-2Xx`k#X()<=Y(w3#c%TpH|es{LK$6Nwa~UM zt1RSflUFSCxJ^1Ow9+OkEaYgH)A4;oKO)FA;+M7Q*FpFR32(!e)DSwT3~d+(7V5p?3z- z!(rH3g(6|Jo2pjShvH5jigX`G`=M&*`sr)!XH{?e>9a@BRz|3KBTQS1$Q#yUaAE+q zegHN)z%srJ;8Gf8#{DR4Hj3h>LKg-}^=Ocv+xj3g3ZA2_eU8>p=)FS6hWKJ`4Ur%* zg!7g{mxgg^8OC{em}#~Vv@V4_BPdo!P!z;aRL4*l3T?)Cz>bZwwWd*A;-j#iNAW9- z2o>pa?(d6p)!q`#WQ@2RS-WYOAlEV4X@OIr?? zcR5a3xWEn?6iOHoI9eukhAu zc?w*$B#(yAFUjNo70#To8qIfyR-@h4Zff_m2j-p4yff|pq3h=Rzbl+vlBK)q#f>Go Ge((=I%ZCI2 delta 1107 zcmYk6T}V@57{`z6q^7+QVJRUI1=2-?bYWpKBt#@iBqAgtOiUy!qN0lkvGC0KHNU3s zJkGhM(@p1`IX4@j5z4P{R2JJwIP4@=?Tp7;@YT1lOSE9#Z9yn)1sttZttdFu zhH$-&ou`e&hGO~cqDVeyM~JqQwRBKl)*&uSR|mqE4uo6>yJ`gi2f~hn2bFZ9Hg&>Q z6y$c{tLmaJ(8ai=SW!36uys@VS;2`Og!?@dEGRh8i(1)Bi>sIBue~JloE%x_ghib6 zZ8`Ck^x<>#F@EYpINDEDT|Z-}AN8kV#S+1;U`3)HbHQpAgk7lL6)PM-un#E908cw& z!fu)DLMB)3nCz^B>}-RukAuVxx<$FHb~6Utj7c|V6bxZ$7$Wguh%w89P^rM}p=#5^ z?`9n)(KL*@JdAM23tU%VdO3H~OTpQfm>U%=zf=|<=9@lZJ|F6)g0mwCPeu^ljv%Ct zvMX26KgtJN9p$uBek}EV#*iQ1wjb3x#_q)!A8~1nTXM$PRVfIJBP7T16$I#err=$G ztR)C53v!w(h;Kc}Rc9vHJ)Xe4Fu|*4OtPz-q|}@wu{Mc%Jj4YLLnIO*)buHYvMI){ zDb!WPj)j5Ruqc$HiY3EbkUvf7(`icIPg9T+fz?FVg%$e|p`~yJU&9QgA7_YVz2dYQ z1<_X|QfDz&C@^Okle5ImNAWdA*?ov|G!AQx zqkf8Wi{h|6xhS&#Tbw@q$H;#|hIUQ6quti-X^+%D1e2zv{AO3E`cvmx6nTHs@ufwv GocRl{U!#x! diff --git a/samples/mass_start/utf8/startlist.csv b/samples/mass_start/utf8/startlist.csv index 1aac0b2..2660480 100644 --- a/samples/mass_start/utf8/startlist.csv +++ b/samples/mass_start/utf8/startlist.csv @@ -1,187 +1,187 @@ -1,GONZALO MONROIG,M,1970,TEAM A,1 -2,LEOPOLDO LINDSAY,M,1973,TEAM A,1 -3,ERNIE GENTILE,M,1988,TEAM B,1 -4,GARTH HEATHERINGTON,M,1964,TEAM C,1 -5,LOYD GAMET,M,1965,TEAM D,1 -6,JACINTO NIPP,M,1957,TEAM E,1 -7,LEONARDO QUILES,M,1964,TEAM E,1 -8,COLE NESTER,M,1955,TEAM F,1 -9,EMILIO AGENA,M,1974,TEAM D,1 -10,ALBA BUSHARD,F,1976,TEAM D,1 -11,SERGIO FULCHER,M,1984,TEAM G,1 -12,DARELL LAFONTANT,M,1992,TEAM C,1 -13,MINERVA LEVEY,F,1967,TEAM H,1 -14,ARNULFO SPROUL,M,1959,TEAM I,1 -15,LAVERA GUIDOTTI,F,1963,TEAM I,1 -16,NATACHA DUROCHER,F,1965,TEAM E,1 -17,ANGLEA GAGE,F,1954,TEAM E,1 -18,JOSE ZALEWSKI,M,1965,TEAM C,1 -19,BOBBIE WILTSE,M,1961,TEAM A,1 -20,YEE HEDLEY,F,1971,TEAM C,1 -21,CHI CAULEY,M,1960,TEAM I,1 -22,BRUNO CROKE,M,1968,TEAM I,1 -23,LEONEL TEETER,M,1968,TEAM A,1 -24,GAVIN KOVACICH,M,1971,TEAM A,1 -25,LESTER LUCERO,M,1981,TEAM J,1 -26,MINA NIMS,F,1966,TEAM I,1 -27,TOBIE RINEY,F,1967,TEAM K,1 -28,VANETTA BECKMANN,F,1960,TEAM I,1 -29,TREVOR READY,M,1958,TEAM L,1 -30,ELOISE MANISCALCO,F,1965,TEAM K,1 -31,BERT HOOS,M,1980,TEAM M,1 -32,BRIAN STAHL,M,1954,TEAM N,1 -33,BILLY BOLTEN,M,1973,TEAM N,1 -34,IVAN MAGWOOD,M,1972,TEAM K,1 -35,FAUSTINO RESTREPO,M,1972,TEAM O,1 -36,SHANICE RALEIGH,F,1975,TEAM I,1 -37,ERIC RAYA,M,1975,TEAM C,1 -38,ADELE LANSBERRY,F,1966,TEAM P,1 -39,RALEIGH WESSELS,M,1981,TEAM Q,1 -40,PEDRO VELIZ,M,1964,TEAM R,1 -41,RANEE MIDGETT,F,1966,TEAM I,1 -42,CLINT BOETTCHER,M,1965,TEAM I,1 -43,IRVIN SHIVELY,M,1968,TEAM D,1 -44,SUNNI GOTTLIEB,F,1969,TEAM R,1 -45,ELLIOTT CHESHIRE,M,1969,TEAM R,1 -46,OMER MCCALLISTER,M,1976,TEAM S,1 -47,TIFFANEY HUBLER,F,1965,TEAM J,1 -48,ASHLEY DAIGNEAULT,M,1971,TEAM O,1 -49,ELIAS QUISENBERRY,M,1964,TEAM T,1 -50,RODGER MOLINAR,M,1970,TEAM U,1 -51,CRUZ TOPE,M,1964,TEAM R,1 -52,BOBBY ARCAND,M,1974,TEAM A,1 -53,ENOCH ENYEART,M,1989,TEAM V,1 -54,BRET CRASS,M,1973,TEAM T,1 -55,MOISES ARCURI,M,1969,TEAM A,1 -56,KIETH STICH,M,1985,TEAM A,1 -57,TASHINA DESCHAINE,F,1973,TEAM A,1 -58,DEVIN LANGSTON,M,1964,TEAM W,1 -59,ALVA CLEVER,M,1973,TEAM A,1 -60,ANTIONE GOVER,M,1959,TEAM X,1 -61,HENRIETTA RICARD,F,1965,TEAM X,1 -98,CARINA HIEB,F,1980,TEAM A,1 -101,AUGUSTUS MAILLOUX,M,1963,TEAM W,1 -102,OTTO FAUNCE,M,1972,TEAM C,1 -104,NOLAN STALTER,M,1964,TEAM B,1 -105,ANIKA AMEZCUA,F,1967,TEAM B,1 -106,ALEXIS MOREFIELD,M,1999,TEAM J,1 -107,KURTIS TWOMEY,M,1976,TEAM Y,1 -108,PARIS LINSLEY,M,1972,TEAM Y,1 -109,SEAN GARTON,M,1994,TEAM S,1 -110,IGNACIO OHERN,M,1996,TEAM Z,1 -112,ANTHONY ARBEITER,M,1959,TEAM B,1 -113,MARC LUEBBERT,M,1987,TEAM O,1 -114,ZENOBIA GRINDER,F,1965,---,1 -115,JOSIAH SABADO,M,1976,TEAM B,1 -116,ELIZABET SHEARER,F,1996,TEAM Y,1 -117,SCOTTY FRITZLER,M,1962,TEAM J,1 -118,TEODORO TOWN,M,1972,TEAM J,1 -119,KRISTA DANIEL,F,1985,TEAM J,1 -120,LUTHER DRYER,M,1973,TEAM J,1 -121,JAE VEASLEY,M,1980,TEAM J,1 -122,MAURICIO RODRIQUES,M,1953,TEAM J,1 -123,LOUISA NOYES,F,1951,TEAM I,1 -124,BRANDA MOOS,F,1966,TEAM I,1 -125,CATRINA CURLIN,F,1971,TEAM I,1 -126,MACK ELSWORTH,M,1969,TEAM A,1 -127,GORDON PURVINES,M,1971,TEAM 1,1 -128,KARRIE MANDELL,F,1946,TEAM 2,1 -129,REED EASTER,M,1947,TEAM 2,1 -130,VEDA SHANKS,F,1979,TEAM K,1 -131,LINDSEY WISNESKI,M,1974,TEAM U,1 -132,FREDERICK GONSALVES,M,1971,TEAM R,1 -133,WINFRED YANG,M,1951,TEAM 3,1 -134,SAMMY TORRANCE,M,1972,TEAM A,1 -135,ARRON BONDY,M,1984,TEAM 4,1 -136,GRACIA KWOK,F,1971,TEAM 1,1 -137,MONTE PAGAN,M,1957,TEAM A,1 -138,ORVILLE KREBSBACH,M,1970,TEAM D,1 -139,ELINOR SENGER,F,1974,TEAM I,1 -140,OCTAVIO CARDELLO,M,1975,TEAM B,1 -141,ARCHIE HERNANDEZ,M,1971,TEAM B,1 -142,GENNY BRIAN,F,1975,TEAM R,1 -143,MIGNON HADSELL,F,1974,TEAM T,1 -144,JORDAN COBLE,M,1958,TEAM 5,1 -145,DARRYL ROSSIN,M,1967,TEAM P,1 -146,EMILIE TRIGGS,F,1979,TEAM C,1 -147,ALI GIRALDO,M,1969,TEAM A,1 -148,QUYEN STENBERG,F,1975,TEAM 6,1 -149,CHAS HUBBELL,M,1975,TEAM 6,1 -150,HANK EFFINGER,M,1981,TEAM J,1 -151,TERRESA DAWDY,F,1959,TEAM I,1 -152,ERA CROLL,F,1969,TEAM I,1 -153,BENJAMIN ADOLPHSEN,M,1945,TEAM 7,1 -154,LEIGHA THORMAN,F,1965,---,1 -155,CLEO HELBERG,M,1962,---,1 -156,DIANNE HARDAGE,F,1965,TEAM R,1 -157,CRIS ZACARIAS,F,1972,TEAM R,1 -158,ERNA FERBER,F,1970,TEAM R,1 -159,JED TEWELL,M,1976,TEAM I,1 -160,DESMOND FORTENBERRY,M,1983,TEAM A,1 -201,ABRAHAM CROCE,M,1980,TEAM A,1 -202,MASON BITTNER,M,1996,TEAM B,1 -203,RUSSEL SUHR,M,1973,TEAM 1,1 -204,BRYANT PLOURDE,M,1974,TEAM 1,1 -205,WERNER PEREA,M,1956,TEAM D,1 -206,CASEY WILLMS,M,1957,TEAM D,1 -207,GENARO LO,M,1961,TEAM D,1 -208,DONNY MCCANE,M,1958,TEAM T,1 -209,EDGARDO ALVARENGA,M,1951,TEAM D,1 -210,RAYMON MORADO,M,1957,TEAM G,1 -211,AURELIO PERRELLA,M,1954,TEAM 8,1 -212,CYRIL MORRIS,M,1956,TEAM 2,1 -213,WALTER HARTZOG,M,1967,TEAM 9,1 -214,CHAD CARRIZALES,M,1670,TEAM 9,1 -215,COLUMBUS BUTTON,M,1964,TEAM 10,1 -216,TOI DEDIOS,F,1962,TEAM I,1 -217,LEO DILLE,M,1967,TEAM B,1 -218,LYDA RAWLINS,F,1979,TEAM C,1 -219,JERRELL PISCITELLI,M,1979,TEAM T,1 -220,KAZUKO PURDUE,F,1971,TEAM I,1 -221,SHANTELL MCGOWIN,F,1973,TEAM A,1 -222,TODD DOKE,M,1971,TEAM J,1 -223,MARCY FORTINO,F,1961,TEAM J,1 -224,HAL KAUFFMAN,M,1959,TEAM K,1 -225,HEATH LANGSAM,M,1968,TEAM D,1 -226,ALBERT ABERLE,M,1966,TEAM K,1 -227,ELI AMAR,M,1971,TEAM C,1 -228,BRETT HARGETT,M,1964,TEAM A,1 -229,THERON RIGG,M,1988,TEAM 6,1 -230,SEYMOUR HERSEY,M,1980,TEAM 6,1 -231,JOSHUA HOWERTON,M,1967,TEAM 3,1 -232,HARLEY BRANDENBURG,M,1982,TEAM V,1 -233,DOMINGA MCNEELY,F,1974,TEAM B,1 -234,WILFRED BERNAL,M,1969,TEAM B,1 -235,CALVIN STANWOOD,M,1958,TEAM I,1 -236,JEFF HUCK,M,1960,TEAM P,1 -237,LANNY SWICK,M,1971,TEAM C,1 -238,JONAS MINNIFIELD,M,1986,TEAM F,1 -239,TOBIAS MATIAS,M,1975,TEAM A,1 -240,RHETT ROSENGARTEN,M,1952,TEAM F,1 -241,ROXANNA MELGAREJO,F,1973,TEAM I,1 -242,REUBEN DELBOSQUE,M,1971,I.A.A.F.,1 -243,MYRON SIMEON,M,1969,I.A.A.F.,1 -244,GLAYDS BIONDO,F,1973,TEAM 11,1 -245,FILIBERTO DUNMIRE,M,1984,TEAM 11,1 -246,SHERWOOD EMORY,M,1977,TEAM 11,1 -247,LUCIUS CAUSEY,M,1994,TEAM I,1 -248,THURMAN WETTER,M,1976,TEAM B,1 -249,LORE CROWE,F,1980,TEAM 1,1 -250,JESUS BRADISH,M,1976,TEAM G,1 -251,HAROLD FICKLIN,M,1980,TEAM 12,1 -252,PHIL HALBROOK,M,1985,TEAM 1,1 -253,MAIRA PAINTER,F,1974,TEAM R,1 -255,GARRET ASHBURN,M,1978,TEAM R,1 -256,KASEY CANCEL,M,1978,TEAM R,1 -257,AVA SIEVERS,F,1981,TEAM R,1 -258,RICK HICKS,M,1965,TEAM U,1 -259,LEWIS FORRY,M,1964,TEAM I,1 -260,RUBIN MCBRYDE,M,1966,TEAM C,1 -261,KAI POZO,F,1996,TEAM Z,1 -262,ROLF COUTURIER,M,1980,TEAM I,1 -263,TRENA KESTEN,F,1990,TEAM W,1 -264,WILFREDO GENGLER,M,1971,TEAM 11,1 -265,GIUSEPPE HASSEN,M,1954,TEAM 13,1 -266,ARMANDINA TOOHEY,F,1979,TEAM I,1 -267,GUILLERMO HUNGER,M,1976,TEAM I,1 -268,CHONG EHLERT,M,1963,TEAM A,1 +1,GONZALO MONROIG,M,1970,TEAM A,,1 +2,LEOPOLDO LINDSAY,M,1973,TEAM A,,1 +3,ERNIE GENTILE,M,1988,TEAM B,,1 +4,GARTH HEATHERINGTON,M,1964,TEAM C,,1 +5,LOYD GAMET,M,1965,TEAM D,,1 +6,JACINTO NIPP,M,1957,TEAM E,,1 +7,LEONARDO QUILES,M,1964,TEAM E,,1 +8,COLE NESTER,M,1955,TEAM F,,1 +9,EMILIO AGENA,M,1974,TEAM D,,1 +10,ALBA BUSHARD,F,1976,TEAM D,,1 +11,SERGIO FULCHER,M,1984,TEAM G,,1 +12,DARELL LAFONTANT,M,1992,TEAM C,,1 +13,MINERVA LEVEY,F,1967,TEAM H,,1 +14,ARNULFO SPROUL,M,1959,TEAM I,,1 +15,LAVERA GUIDOTTI,F,1963,TEAM I,,1 +16,NATACHA DUROCHER,F,1965,TEAM E,,1 +17,ANGLEA GAGE,F,1954,TEAM E,,1 +18,JOSE ZALEWSKI,M,1965,TEAM C,,1 +19,BOBBIE WILTSE,M,1961,TEAM A,,1 +20,YEE HEDLEY,F,1971,TEAM C,,1 +21,CHI CAULEY,M,1960,TEAM I,,1 +22,BRUNO CROKE,M,1968,TEAM I,,1 +23,LEONEL TEETER,M,1968,TEAM A,,1 +24,GAVIN KOVACICH,M,1971,TEAM A,,1 +25,LESTER LUCERO,M,1981,TEAM J,,1 +26,MINA NIMS,F,1966,TEAM I,,1 +27,TOBIE RINEY,F,1967,TEAM K,,1 +28,VANETTA BECKMANN,F,1960,TEAM I,,1 +29,TREVOR READY,M,1958,TEAM L,,1 +30,ELOISE MANISCALCO,F,1965,TEAM K,,1 +31,BERT HOOS,M,1980,TEAM M,,1 +32,BRIAN STAHL,M,1954,TEAM N,,1 +33,BILLY BOLTEN,M,1973,TEAM N,,1 +34,IVAN MAGWOOD,M,1972,TEAM K,,1 +35,FAUSTINO RESTREPO,M,1972,TEAM O,,1 +36,SHANICE RALEIGH,F,1975,TEAM I,,1 +37,ERIC RAYA,M,1975,TEAM C,,1 +38,ADELE LANSBERRY,F,1966,TEAM P,,1 +39,RALEIGH WESSELS,M,1981,TEAM Q,,1 +40,PEDRO VELIZ,M,1964,TEAM R,,1 +41,RANEE MIDGETT,F,1966,TEAM I,,1 +42,CLINT BOETTCHER,M,1965,TEAM I,,1 +43,IRVIN SHIVELY,M,1968,TEAM D,,1 +44,SUNNI GOTTLIEB,F,1969,TEAM R,,1 +45,ELLIOTT CHESHIRE,M,1969,TEAM R,,1 +46,OMER MCCALLISTER,M,1976,TEAM S,,1 +47,TIFFANEY HUBLER,F,1965,TEAM J,,1 +48,ASHLEY DAIGNEAULT,M,1971,TEAM O,,1 +49,ELIAS QUISENBERRY,M,1964,TEAM T,,1 +50,RODGER MOLINAR,M,1970,TEAM U,,1 +51,CRUZ TOPE,M,1964,TEAM R,,1 +52,BOBBY ARCAND,M,1974,TEAM A,,1 +53,ENOCH ENYEART,M,1989,TEAM V,,1 +54,BRET CRASS,M,1973,TEAM T,,1 +55,MOISES ARCURI,M,1969,TEAM A,,1 +56,KIETH STICH,M,1985,TEAM A,,1 +57,TASHINA DESCHAINE,F,1973,TEAM A,,1 +58,DEVIN LANGSTON,M,1964,TEAM W,,1 +59,ALVA CLEVER,M,1973,TEAM A,,1 +60,ANTIONE GOVER,M,1959,TEAM X,,1 +61,HENRIETTA RICARD,F,1965,TEAM X,,1 +98,CARINA HIEB,F,1980,TEAM A,,1 +101,AUGUSTUS MAILLOUX,M,1963,TEAM W,,1 +102,OTTO FAUNCE,M,1972,TEAM C,,1 +104,NOLAN STALTER,M,1964,TEAM B,,1 +105,ANIKA AMEZCUA,F,1967,TEAM B,,1 +106,ALEXIS MOREFIELD,M,1999,TEAM J,,1 +107,KURTIS TWOMEY,M,1976,TEAM Y,,1 +108,PARIS LINSLEY,M,1972,TEAM Y,,1 +109,SEAN GARTON,M,1994,TEAM S,,1 +110,IGNACIO OHERN,M,1996,TEAM Z,,1 +112,ANTHONY ARBEITER,M,1959,TEAM B,,1 +113,MARC LUEBBERT,M,1987,TEAM O,,1 +114,ZENOBIA GRINDER,F,1965,---,,1 +115,JOSIAH SABADO,M,1976,TEAM B,,1 +116,ELIZABET SHEARER,F,1996,TEAM Y,,1 +117,SCOTTY FRITZLER,M,1962,TEAM J,,1 +118,TEODORO TOWN,M,1972,TEAM J,,1 +119,KRISTA DANIEL,F,1985,TEAM J,,1 +120,LUTHER DRYER,M,1973,TEAM J,,1 +121,JAE VEASLEY,M,1980,TEAM J,,1 +122,MAURICIO RODRIQUES,M,1953,TEAM J,,1 +123,LOUISA NOYES,F,1951,TEAM I,,1 +124,BRANDA MOOS,F,1966,TEAM I,,1 +125,CATRINA CURLIN,F,1971,TEAM I,,1 +126,MACK ELSWORTH,M,1969,TEAM A,,1 +127,GORDON PURVINES,M,1971,TEAM 1,,1 +128,KARRIE MANDELL,F,1946,TEAM 2,,1 +129,REED EASTER,M,1947,TEAM 2,,1 +130,VEDA SHANKS,F,1979,TEAM K,,1 +131,LINDSEY WISNESKI,M,1974,TEAM U,,1 +132,FREDERICK GONSALVES,M,1971,TEAM R,,1 +133,WINFRED YANG,M,1951,TEAM 3,,1 +134,SAMMY TORRANCE,M,1972,TEAM A,,1 +135,ARRON BONDY,M,1984,TEAM 4,,1 +136,GRACIA KWOK,F,1971,TEAM 1,,1 +137,MONTE PAGAN,M,1957,TEAM A,,1 +138,ORVILLE KREBSBACH,M,1970,TEAM D,,1 +139,ELINOR SENGER,F,1974,TEAM I,,1 +140,OCTAVIO CARDELLO,M,1975,TEAM B,,1 +141,ARCHIE HERNANDEZ,M,1971,TEAM B,,1 +142,GENNY BRIAN,F,1975,TEAM R,,1 +143,MIGNON HADSELL,F,1974,TEAM T,,1 +144,JORDAN COBLE,M,1958,TEAM 5,,1 +145,DARRYL ROSSIN,M,1967,TEAM P,,1 +146,EMILIE TRIGGS,F,1979,TEAM C,,1 +147,ALI GIRALDO,M,1969,TEAM A,,1 +148,QUYEN STENBERG,F,1975,TEAM 6,,1 +149,CHAS HUBBELL,M,1975,TEAM 6,,1 +150,HANK EFFINGER,M,1981,TEAM J,,1 +151,TERRESA DAWDY,F,1959,TEAM I,,1 +152,ERA CROLL,F,1969,TEAM I,,1 +153,BENJAMIN ADOLPHSEN,M,1945,TEAM 7,,1 +154,LEIGHA THORMAN,F,1965,---,,1 +155,CLEO HELBERG,M,1962,---,,1 +156,DIANNE HARDAGE,F,1965,TEAM R,,1 +157,CRIS ZACARIAS,F,1972,TEAM R,,1 +158,ERNA FERBER,F,1970,TEAM R,,1 +159,JED TEWELL,M,1976,TEAM I,,1 +160,DESMOND FORTENBERRY,M,1983,TEAM A,,1 +201,ABRAHAM CROCE,M,1980,TEAM A,,1 +202,MASON BITTNER,M,1996,TEAM B,,1 +203,RUSSEL SUHR,M,1973,TEAM 1,,1 +204,BRYANT PLOURDE,M,1974,TEAM 1,,1 +205,WERNER PEREA,M,1956,TEAM D,,1 +206,CASEY WILLMS,M,1957,TEAM D,,1 +207,GENARO LO,M,1961,TEAM D,,1 +208,DONNY MCCANE,M,1958,TEAM T,,1 +209,EDGARDO ALVARENGA,M,1951,TEAM D,,1 +210,RAYMON MORADO,M,1957,TEAM G,,1 +211,AURELIO PERRELLA,M,1954,TEAM 8,,1 +212,CYRIL MORRIS,M,1956,TEAM 2,,1 +213,WALTER HARTZOG,M,1967,TEAM 9,,1 +214,CHAD CARRIZALES,M,1670,TEAM 9,,1 +215,COLUMBUS BUTTON,M,1964,TEAM 10,,1 +216,TOI DEDIOS,F,1962,TEAM I,,1 +217,LEO DILLE,M,1967,TEAM B,,1 +218,LYDA RAWLINS,F,1979,TEAM C,,1 +219,JERRELL PISCITELLI,M,1979,TEAM T,,1 +220,KAZUKO PURDUE,F,1971,TEAM I,,1 +221,SHANTELL MCGOWIN,F,1973,TEAM A,,1 +222,TODD DOKE,M,1971,TEAM J,,1 +223,MARCY FORTINO,F,1961,TEAM J,,1 +224,HAL KAUFFMAN,M,1959,TEAM K,,1 +225,HEATH LANGSAM,M,1968,TEAM D,,1 +226,ALBERT ABERLE,M,1966,TEAM K,,1 +227,ELI AMAR,M,1971,TEAM C,,1 +228,BRETT HARGETT,M,1964,TEAM A,,1 +229,THERON RIGG,M,1988,TEAM 6,,1 +230,SEYMOUR HERSEY,M,1980,TEAM 6,,1 +231,JOSHUA HOWERTON,M,1967,TEAM 3,,1 +232,HARLEY BRANDENBURG,M,1982,TEAM V,,1 +233,DOMINGA MCNEELY,F,1974,TEAM B,,1 +234,WILFRED BERNAL,M,1969,TEAM B,,1 +235,CALVIN STANWOOD,M,1958,TEAM I,,1 +236,JEFF HUCK,M,1960,TEAM P,,1 +237,LANNY SWICK,M,1971,TEAM C,,1 +238,JONAS MINNIFIELD,M,1986,TEAM F,,1 +239,TOBIAS MATIAS,M,1975,TEAM A,,1 +240,RHETT ROSENGARTEN,M,1952,TEAM F,,1 +241,ROXANNA MELGAREJO,F,1973,TEAM I,,1 +242,REUBEN DELBOSQUE,M,1971,I.A.A.F.,,1 +243,MYRON SIMEON,M,1969,I.A.A.F.,,1 +244,GLAYDS BIONDO,F,1973,TEAM 11,,1 +245,FILIBERTO DUNMIRE,M,1984,TEAM 11,,1 +246,SHERWOOD EMORY,M,1977,TEAM 11,,1 +247,LUCIUS CAUSEY,M,1994,TEAM I,,1 +248,THURMAN WETTER,M,1976,TEAM B,,1 +249,LORE CROWE,F,1980,TEAM 1,,1 +250,JESUS BRADISH,M,1976,TEAM G,,1 +251,HAROLD FICKLIN,M,1980,TEAM 12,,1 +252,PHIL HALBROOK,M,1985,TEAM 1,,1 +253,MAIRA PAINTER,F,1974,TEAM R,,1 +255,GARRET ASHBURN,M,1978,TEAM R,,1 +256,KASEY CANCEL,M,1978,TEAM R,,1 +257,AVA SIEVERS,F,1981,TEAM R,,1 +258,RICK HICKS,M,1965,TEAM U,,1 +259,LEWIS FORRY,M,1964,TEAM I,,1 +260,RUBIN MCBRYDE,M,1966,TEAM C,,1 +261,KAI POZO,F,1996,TEAM Z,,1 +262,ROLF COUTURIER,M,1980,TEAM I,,1 +263,TRENA KESTEN,F,1990,TEAM W,,1 +264,WILFREDO GENGLER,M,1971,TEAM 11,,1 +265,GIUSEPPE HASSEN,M,1954,TEAM 13,,1 +266,ARMANDINA TOOHEY,F,1979,TEAM I,,1 +267,GUILLERMO HUNGER,M,1976,TEAM I,,1 +268,CHONG EHLERT,M,1963,TEAM A,,1 diff --git a/samples/relay/latin1/startlist.csv b/samples/relay/latin1/startlist.csv index c52b1c1..c7b5076 100644 --- a/samples/relay/latin1/startlist.csv +++ b/samples/relay/latin1/startlist.csv @@ -1,123 +1,123 @@ -1,GRANT OVELLETTE,M,1958,TEAM M 1,1 -1,RANDELL NELMS,M,1954,TEAM M 1,2 -1,GERARD MCCUTCHEON,M,1978,TEAM M 1,3 -2,MALIKA OUZTS,F,1950,TEAM B 1,1 -2,KACY BAPTIST,F,1982,TEAM B 1,2 -2,BASILIA MCINTIRE,F,1985,TEAM B 1,3 -3,MELVIN MIDDLEBROOKS,M,1969,TEAM B 2,1 -3,LUPE MUTO,M,1979,TEAM B 2,2 -3,BRENTON RENCH,M,1968,TEAM B 2,3 -4,NOEL MARGULIES,M,1988,TEAM B 3,1 -4,KENT MASTERSON,M,1968,TEAM B 3,2 -4,DANA GOODNIGHT,M,1976,TEAM B 3,3 -5,CORDELL NAKAMOTO,M,1980,TEAM B 4,1 -5,JAMIE DESCHENES,M,1998,TEAM B 4,2 -5,ORVAL HANLINE,M,1983,TEAM B 4,3 -6,GAYLE HARD,M,1963,TEAM B 5,1 -6,FORREST LIPPOLD,M,1975,TEAM B 5,2 -6,MARTIN HAGERTY,M,1970,TEAM B 5,3 -7,ELLAN HINESLEY,F,1986,TEAM A 1,1 -7,NATASHIA TOBIAS,F,1963,TEAM A 1,2 -7,RHODA CANSLER,F,1960,TEAM A 1,3 -8,SHARLENE HUERTAS,F,1981,TEAM A 2,1 -8,SHILA VILLICANA,F,1984,TEAM A 2,2 -8,CHARLSIE KEMMER,F,1987,TEAM A 2,3 -9,GREGG OLDEN,M,1956,TEAM A 3,1 -9,NOAH CIPRIANI,M,1990,TEAM A 3,2 -9,LAVERNE GIVEN,M,1980,TEAM A 3,3 -10,JACQUES CARDWELL,M,1961,TEAM A 4,1 -10,BRODERICK BELOW,M,1970,TEAM A 4,2 -10,JAIME IVORY,M,1992,TEAM A 4,3 -11,JACK DIAMOND,M,1952,TEAM A 5,1 -11,BYRON BROOKINS,M,1992,TEAM A 5,2 -11,DWAIN GREENING,M,1990,TEAM A 5,3 -12,LUCAS GIGUERE,M,1971,TEAM H,1 -12,SETH HAJDUK,M,1972,TEAM H,2 -12,SCOT LLANES,M,1957,TEAM H,3 -13,EZRA GOUPIL,M,1978,TEAM L 1,1 -13,LINCOLN COMFORT,M,1992,TEAM L 1,2 -13,MARCELO ULM,M,1969,TEAM L 1,3 -14,ANDERSON STRETCH,M,1965,TEAM E 1,1 -14,GAYLORD STANFILL,M,1959,TEAM E 1,2 -14,LAMAR MEIKLE,M,1997,TEAM E 1,3 -15,MOHAMMED LILES,M,1964,TEAM E 2,1 -15,LUCIO MANCILLA,M,1989,TEAM E 2,2 -15,LELAND MITSCHKE,M,1950,TEAM E 2,3 -16,KAREY BACHER,F,1962,TEAM E 3,1 -16,GEARLDINE ESPANA,F,1994,TEAM E 3,2 -16,ANNITA DURR,F,1972,TEAM E 3,3 -17,KENNY HURSTON,M,1996,TEAM J 1,1 -17,KATIA MATTICE,F,1990,TEAM J 1,2 -17,IVORY DONALDSON,M,1966,TEAM J 1,3 -18,TRENT EILER,M,1987,TEAM J 2,1 -18,WENDELL NYBERG,M,1977,TEAM J 2,2 -18,ERICH WHITCOMB,M,1961,TEAM J 2,3 -19,ABRAM PRIDMORE,M,1987,TEAM C 1,1 -19,MORTON HOEFT,M,1955,TEAM C 1,2 -19,GIL ROSENBLUM,M,1952,TEAM C 1,3 -20,JUSTIN SARMIENTO,M,1997,TEAM C 2,1 -20,ROMAN PICKRON,M,1984,TEAM C 2,2 -20,DARIN PATERNO,M,1983,TEAM C 2,3 -21,KIRBY ESTERLY,M,1954,TEAM C 3,1 -21,DAREN SOLLEY,M,1959,TEAM C 3,2 -21,KENNITH VANDERLINDEN,M,1951,TEAM C 3,3 -22,MEI GLADDING,F,1954,TEAM C 4,1 -22,ELBA WESTERGARD,F,1977,TEAM C 4,2 -22,AISHA GRANDERSON,F,1967,TEAM C 4,3 -23,DAYSI SMITHSON,F,1989,TEAM O 1,1 -23,HOSEA KOLL,M,1974,TEAM O 1,2 -23,JAMEY BAINS,M,1986,TEAM O 1,3 -24,MINDY HULSEY,F,1957,TEAM O 2,1 -24,MISTY REILLY,F,1987,TEAM O 2,2 -24,CRISTINA BROMBERG,F,1978,TEAM O 2,3 -25,JERROD HOOP,M,1968,TEAM O 3,1 -25,ISIDRO RENE,M,1985,TEAM O 3,2 -25,CARSON CUSTARD,M,1966,TEAM O 3,3 -26,JULIAN BLAS,M,1970,TEAM D,1 -26,HAI TOMKO,M,1963,TEAM D,2 -26,MARCELLUS REPPERT,M,1958,TEAM D,3 -27,TRUDY ASHER,F,1987,TEAM G 1,1 -27,VICENTA GRATTON,F,1991,TEAM G 1,2 -27,GABRIELE TERRIO,F,1952,TEAM G 1,3 -28,ANTONY VICARI,M,1974,TEAM M 2,1 -28,EMANUEL HARE,M,1988,TEAM M 2,2 -28,JEFFERSON LANDRITH,M,1994,TEAM M 2,3 -29,MICKEY DORIA,M,1999,TEAM M 3,1 -29,SIDNEY RIFE,M,1977,TEAM M 3,2 -29,BARRY MISKELL,M,1988,TEAM M 3,3 -30,KRISTYN LABOMBARD,F,1993,TEAM M 4,1 -30,DANYELLE MARENCO,F,1985,TEAM M 4,2 -30,SHERYL OSTENDORF,F,1956,TEAM M 4,3 -31,LEE HOEKSTRA,M,1974,TEAM M 5,1 -31,NICKY KIRTON,M,1982,TEAM M 5,2 -31,TIM DUNKELBERGER,M,1992,TEAM M 5,3 -32,ROCCO SUPER,M,1972,TEAM G 2,1 -32,JASPER FONNER,M,1979,TEAM G 2,2 -32,RICARDO BELMONT,M,1956,TEAM G 2,3 -33,ROSCOE KROK,M,1992,TEAM A 6,1 -33,DAVID BOLL,M,1960,TEAM A 6,2 -33,ROY SMITHEY,M,1982,TEAM A 6,3 -34,OREN HOFFMEISTER,M,1961,TEAM I 1,1 -34,RYAN TAITT,M,1988,TEAM I 1,2 -34,WILTON WEMMER,M,1963,TEAM I 1,3 -35,CHASE THEODORE,M,1964,TEAM I 2,1 -35,REFUGIO LABER,M,1993,TEAM I 2,2 -35,BRIANNA ZHOU,F,1955,TEAM I 2,3 -36,JUDE COWBOY,M,1979,TEAM L 2,1 -36,HUBERT SCHLESINGER,M,1980,TEAM L 2,2 -36,BENNETT RIDENOUR,M,1960,TEAM L 2,3 -37,PAUL SOTO,M,1955,TEAM N,1 -37,LIONEL BENFER,M,1973,TEAM N,2 -37,JAME GUARD,M,1967,TEAM N,3 -38,DREW TIGUE,M,1959,TEAM G 3,1 -38,SALVATORE ERLANDSON,M,1987,TEAM G 3,2 -38,TOMMIE HITTLE,M,1997,TEAM G 3,3 -39,DEE GODING,M,1969,TEAM F,1 -39,RONNIE TURCO,M,1966,TEAM F,2 -39,DUNCAN ISHIDA,M,1957,TEAM F,3 -40,KIRK PROVENCAL,M,1969,TEAM I 3,1 -40,ELAINE HAYDEN,F,1990,TEAM I 3,2 -40,MAURITA HAWN,F,1997,TEAM I 3,3 -41,LEIGH SPONAUGLE,M,1964,TEAM K,1 -41,ROGELIO HARMER,M,1962,TEAM K,2 -41,JUNIOR BUSH,M,1974,TEAM K,3 +1,GRANT OVELLETTE,M,1958,TEAM M,1,1 +1,RANDELL NELMS,M,1954,TEAM M,1,2 +1,GERARD MCCUTCHEON,M,1978,TEAM M,1,3 +2,MALIKA OUZTS,F,1950,TEAM B,1,1 +2,KACY BAPTIST,F,1982,TEAM B,1,2 +2,BASILIA MCINTIRE,F,1985,TEAM B,1,3 +3,MELVIN MIDDLEBROOKS,M,1969,TEAM B,2,1 +3,LUPE MUTO,M,1979,TEAM B,2,2 +3,BRENTON RENCH,M,1968,TEAM B,2,3 +4,NOEL MARGULIES,M,1988,TEAM B,3,1 +4,KENT MASTERSON,M,1968,TEAM B,3,2 +4,DANA GOODNIGHT,M,1976,TEAM B,3,3 +5,CORDELL NAKAMOTO,M,1980,TEAM B,4,1 +5,JAMIE DESCHENES,M,1998,TEAM B,4,2 +5,ORVAL HANLINE,M,1983,TEAM B,4,3 +6,GAYLE HARD,M,1963,TEAM B,5,1 +6,FORREST LIPPOLD,M,1975,TEAM B,5,2 +6,MARTIN HAGERTY,M,1970,TEAM B,5,3 +7,ELLAN HINESLEY,F,1986,TEAM A,1,1 +7,NATASHIA TOBIAS,F,1963,TEAM A,1,2 +7,RHODA CANSLER,F,1960,TEAM A,1,3 +8,SHARLENE HUERTAS,F,1981,TEAM A,2,1 +8,SHILA VILLICANA,F,1984,TEAM A,2,2 +8,CHARLSIE KEMMER,F,1987,TEAM A,2,3 +9,GREGG OLDEN,M,1956,TEAM A,3,1 +9,NOAH CIPRIANI,M,1990,TEAM A,3,2 +9,LAVERNE GIVEN,M,1980,TEAM A,3,3 +10,JACQUES CARDWELL,M,1961,TEAM A,4,1 +10,BRODERICK BELOW,M,1970,TEAM A,4,2 +10,JAIME IVORY,M,1992,TEAM A,4,3 +11,JACK DIAMOND,M,1952,TEAM A,5,1 +11,BYRON BROOKINS,M,1992,TEAM A,5,2 +11,DWAIN GREENING,M,1990,TEAM A,5,3 +12,LUCAS GIGUERE,M,1971,TEAM H,1,1 +12,SETH HAJDUK,M,1972,TEAM H,1,2 +12,SCOT LLANES,M,1957,TEAM H,1,3 +13,EZRA GOUPIL,M,1978,TEAM L,1,1 +13,LINCOLN COMFORT,M,1992,TEAM L,1,2 +13,MARCELO ULM,M,1969,TEAM L,1,3 +14,ANDERSON STRETCH,M,1965,TEAM E,1,1 +14,GAYLORD STANFILL,M,1959,TEAM E,1,2 +14,LAMAR MEIKLE,M,1997,TEAM E,1,3 +15,MOHAMMED LILES,M,1964,TEAM E,2,1 +15,LUCIO MANCILLA,M,1989,TEAM E,2,2 +15,LELAND MITSCHKE,M,1950,TEAM E,2,3 +16,KAREY BACHER,F,1962,TEAM E,3,1 +16,GEARLDINE ESPANA,F,1994,TEAM E,3,2 +16,ANNITA DURR,F,1972,TEAM E,3,3 +17,KENNY HURSTON,M,1996,TEAM J,1,1 +17,KATIA MATTICE,F,1990,TEAM J,1,2 +17,IVORY DONALDSON,M,1966,TEAM J,1,3 +18,TRENT EILER,M,1987,TEAM J,2,1 +18,WENDELL NYBERG,M,1977,TEAM J,2,2 +18,ERICH WHITCOMB,M,1961,TEAM J,2,3 +19,ABRAM PRIDMORE,M,1987,TEAM C,1,1 +19,MORTON HOEFT,M,1955,TEAM C,1,2 +19,GIL ROSENBLUM,M,1952,TEAM C,1,3 +20,JUSTIN SARMIENTO,M,1997,TEAM C,2,1 +20,ROMAN PICKRON,M,1984,TEAM C,2,2 +20,DARIN PATERNO,M,1983,TEAM C,2,3 +21,KIRBY ESTERLY,M,1954,TEAM C,3,1 +21,DAREN SOLLEY,M,1959,TEAM C,3,2 +21,KENNITH VANDERLINDEN,M,1951,TEAM C,3,3 +22,MEI GLADDING,F,1954,TEAM C,4,1 +22,ELBA WESTERGARD,F,1977,TEAM C,4,2 +22,AISHA GRANDERSON,F,1967,TEAM C,4,3 +23,DAYSI SMITHSON,F,1989,TEAM O,1,1 +23,HOSEA KOLL,M,1974,TEAM O,1,2 +23,JAMEY BAINS,M,1986,TEAM O,1,3 +24,MINDY HULSEY,F,1957,TEAM O,2,1 +24,MISTY REILLY,F,1987,TEAM O,2,2 +24,CRISTINA BROMBERG,F,1978,TEAM O,2,3 +25,JERROD HOOP,M,1968,TEAM O,3,1 +25,ISIDRO RENE,M,1985,TEAM O,3,2 +25,CARSON CUSTARD,M,1966,TEAM O,3,3 +26,JULIAN BLAS,M,1970,TEAM D,1,1 +26,HAI TOMKO,M,1963,TEAM D,1,2 +26,MARCELLUS REPPERT,M,1958,TEAM D,1,3 +27,TRUDY ASHER,F,1987,TEAM G,1,1 +27,VICENTA GRATTON,F,1991,TEAM G,1,2 +27,GABRIELE TERRIO,F,1952,TEAM G,1,3 +28,ANTONY VICARI,M,1974,TEAM M,2,1 +28,EMANUEL HARE,M,1988,TEAM M,2,2 +28,JEFFERSON LANDRITH,M,1994,TEAM M,2,3 +29,MICKEY DORIA,M,1999,TEAM M,3,1 +29,SIDNEY RIFE,M,1977,TEAM M,3,2 +29,BARRY MISKELL,M,1988,TEAM M,3,3 +30,KRISTYN LABOMBARD,F,1993,TEAM M,4,1 +30,DANYELLE MARENCO,F,1985,TEAM M,4,2 +30,SHERYL OSTENDORF,F,1956,TEAM M,4,3 +31,LEE HOEKSTRA,M,1974,TEAM M,5,1 +31,NICKY KIRTON,M,1982,TEAM M,5,2 +31,TIM DUNKELBERGER,M,1992,TEAM M,5,3 +32,ROCCO SUPER,M,1972,TEAM G,2,1 +32,JASPER FONNER,M,1979,TEAM G,2,2 +32,RICARDO BELMONT,M,1956,TEAM G,2,3 +33,ROSCOE KROK,M,1992,TEAM A,6,1 +33,DAVID BOLL,M,1960,TEAM A,6,2 +33,ROY SMITHEY,M,1982,TEAM A,6,3 +34,OREN HOFFMEISTER,M,1961,TEAM I,1,1 +34,RYAN TAITT,M,1988,TEAM I,1,2 +34,WILTON WEMMER,M,1963,TEAM I,1,3 +35,CHASE THEODORE,M,1964,TEAM I,2,1 +35,REFUGIO LABER,M,1993,TEAM I,2,2 +35,BRIANNA ZHOU,F,1955,TEAM I,2,3 +36,JUDE COWBOY,M,1979,TEAM L,2,1 +36,HUBERT SCHLESINGER,M,1980,TEAM L,2,2 +36,BENNETT RIDENOUR,M,1960,TEAM L,2,3 +37,PAUL SOTO,M,1955,TEAM N,1,1 +37,LIONEL BENFER,M,1973,TEAM N,1,2 +37,JAME GUARD,M,1967,TEAM N,1,3 +38,DREW TIGUE,M,1959,TEAM G,3,1 +38,SALVATORE ERLANDSON,M,1987,TEAM G,3,2 +38,TOMMIE HITTLE,M,1997,TEAM G,3,3 +39,DEE GODING,M,1969,TEAM F,1,1 +39,RONNIE TURCO,M,1966,TEAM F,1,2 +39,DUNCAN ISHIDA,M,1957,TEAM F,1,3 +40,KIRK PROVENCAL,M,1969,TEAM I,3,1 +40,ELAINE HAYDEN,F,1990,TEAM I,3,2 +40,MAURITA HAWN,F,1997,TEAM I,3,3 +41,LEIGH SPONAUGLE,M,1964,TEAM K,1,1 +41,ROGELIO HARMER,M,1962,TEAM K,1,2 +41,JUNIOR BUSH,M,1974,TEAM K,1,3 diff --git a/samples/relay/relay.crd b/samples/relay/relay.crd index d22725d3e76fcc32873a5d6d62d1bb7c8d3fe0e1..d85d4e221cf6bb5862e52ace9cf477cd133e3eb5 100644 GIT binary patch delta 2919 zcmZveO-NKx6vv-4T2s!UgbE9JNQ)>4!ORi+z{Y9vBR@dIMToSDaOEmmh?a22nb8@? zQRj^_j`QgV5v|HvNQAhEXb~>NMYJ*_R}tc_?7e#?cys0~E_2Us&O7&i&i!2f;n?`@ zuqldS)tjPKov%3eTor1WP%T2W3bkCQ6+%5G)Z;?63H5|fPYShCsP;E1fY2)AV6W)b zzqDvK1THef?PoUcEraDY4<@xsk7$yaWS-QA1kERPq0&#b=XgW zAYStmC5Zp}Nj8YPrr01+9`8;;V^KO7Qa!!BSGk}T9kTiEeI~zIsD&o%#exek~M!iLqsCpoFO6++d?E$w+u4C<6MZOgx>oh zq8;(|Sr(7Y5`pObX_k$BI?M_j3X^m&NG43Cxl^XI&*N)zLi0$(% z9-!DIm89lLmWcP}iEhMo3nY2OqYJF}CXekA*1JE#Dv3p)t!V$?kiU3uhej%h-V++D z`-?_O)hlaqAqovzd{sZu(H@MF`Xf$7iD1NgJifX}&VTeCU1Vc_;Bk4372Fd8x7>@N z7_`XF=NRMclf~;?OcQne*7zZANfSlKpx(360v%puQ}ySg(>qDdNKTNc`6=VGov9_Gl~1#6qik%tcAgB+2L_|{6{iW*%h?2q>=g@G)2 z@&#tq$>VUIt-($nx>5FO;Zl6O3a)YecGPF3?C9v|kN#`b+ZDZ?(VOwUJf%1KIyBqH zYs_pL>%nZd6Wb`I`G5B~0miLhb}&vvvu&J1X8SI&jar)jH!5Yedx(AZ9s&1tTY0pF delta 3239 zcmZve%S%;J7{!m8W#u*li4r;88r39xvCWm&Q2 zvGmC^@u!~JjveFJv5p<**oPcD-mwom_7TTUaO|Uweax|sJ9gqLTPf#6vUSHQwF<2o z%ZEqjI_jziwm7QL1J@mO#RZE@xvxcl4_j2eNBO2jm3m-OtIF`e+pQD{MkB2%$D{lz z!OS*6+0-UPT5D6+Jw4Of1^0$_mE}>sXcx+N+6DKL4uXYdqEH8w1Agitcfbps6dtg# zQz&1NU`m(Dc7;dzy)MBhEWz(xf_q+2aPJBVM(=}kLg1d-Ei6cb1Q)wig^uY_1-cwR zf;}qTHA}VWw$?*o0MkMg2CzOvvy>XRD8blXiVbCDFU1BNl;G!HiUehPpU|_hPl&YI zN8wSP)K6PhY2aN6&h(Qzl-vE(6VU&RCIW1h;2OhXqf8y3i2&;dC@0{;0F4RwOH!5% z3gsaQZVU?U=d~(#oe&s3)`D_b(<(ukJS60-8=_UZg^7mfP5|5Eea*^oY>2R)XOXA?NmpD%CloDpx-lRn_|4DE$YO8;j&IS_;5g2`-G$?%*ZzV~hp_ z%o|t5u8jcf8yA!t<1`?Yz6rtT(FCmzluHw|Wq^s30=z#dxQ8XUC6(t+QBJH<^AzO- zd^;tqXX-SS<0h<|rc(qMmXw>*G*N|7UYntEz@{0B1h_gwX9F;0R#4W?(kek2nWgZ! zPPb-hivbJ5loK!%R)zXwSe58=b1F|im{XTrX9J5Co}(`Wz@KxJ5U?boighreiu8ww zX?ZrP{H|^Y+z_Qgz?V^Bw4JD`(N*)ROzU}75Qy2`-TiGot>Vmc(L5=8zv;`#$}s#O zGhZnp%M^530=xW=1@=GB&@h{X=5%;Wz}N(gO~Cd{_C3Jhk+}a^81Pv)$kc40$JD%# zM8-j&;~?f8=A;o2^gDz@wDbP_4ETf*e_si4+{_t|1XQrDxp;| z2hr0EwFjHwZ#*0hjKhJMtq8ad6->Ax_RLRV%;ENg0pnV1CD_5iZn}Eq`z)C9^kpuQ S&q8z7R2fae>&@qCJ>d`RmKc5j diff --git a/startlistmodel.cpp b/startlistmodel.cpp index 219e50e..8f4258d 100644 --- a/startlistmodel.cpp +++ b/startlistmodel.cpp @@ -15,6 +15,7 @@ * along with this program. If not, see . * *****************************************************************************/ +#include "lbchronorace.hpp" #include "startlistmodel.hpp" #include "lbcrexception.hpp" @@ -23,7 +24,8 @@ QDataStream &operator<<(QDataStream &out, StartListModel const &data) out << data.startList << quint32(data.legCount) << quint32(data.maxBib) - << quint32(data.competitorNameMaxWidth); + << quint32(data.competitorNameWidthMax) + << quint32(data.teamNameWidthMax); return out; } @@ -32,16 +34,25 @@ QDataStream &operator>>(QDataStream &in, StartListModel &data) { quint32 legCount; quint32 maxBib; - quint32 competitorNameMaxWidth; + quint32 competitorNameWidthMax; + quint32 teamNameWidthMax; in >> data.startList >> legCount >> maxBib - >> competitorNameMaxWidth; + >> competitorNameWidthMax; + + if (LBChronoRace::binFormat > LBCHRONORACE_BIN_FMT_v2) { + in >> teamNameWidthMax; + } else { + teamNameWidthMax = 0; + data.refreshCounters(0); + } data.legCount = legCount; data.maxBib = maxBib; - data.competitorNameMaxWidth = competitorNameMaxWidth; + data.competitorNameWidthMax = competitorNameWidthMax; + data.teamNameWidthMax = teamNameWidthMax; return in; } @@ -52,24 +63,37 @@ void StartListModel::refreshCounters(int r) uint bib; uint leg; uint nameWidth; + uint clubWidth; + uint teamWidth; Q_UNUSED(r) legCount = 0; maxBib = 0; - competitorNameMaxWidth = 0; + competitorNameWidthMax = 0; + teamNameWidthMax = 0; for (auto const &comp : startList) { bib = comp.getBib(); offset = comp.getOffset(); leg = static_cast((offset < 0) ? qAbs(offset) : 1); - nameWidth = static_cast(comp.getName().length()); + nameWidth = static_cast(comp.getName().simplified().length()); + clubWidth = static_cast(comp.getClub().simplified().length()); + teamWidth = static_cast(comp.getTeam().simplified().length()); + + if (clubWidth != 0) { + teamWidth += clubWidth; + if (teamWidth != 0) + teamWidth++; + } if (bib > maxBib) maxBib = bib; if (leg > legCount) legCount = leg; - if (nameWidth > competitorNameMaxWidth) - competitorNameMaxWidth = nameWidth; + if (nameWidth > competitorNameWidthMax) + competitorNameWidthMax = nameWidth; + if (teamWidth > teamNameWidthMax) + teamNameWidthMax = teamWidth; } } @@ -105,6 +129,8 @@ QVariant StartListModel::data(QModelIndex const &index, int role) const return QVariant(Competitor::toSexString(startList.at(index.row()).getSex())); case static_cast(Competitor::Field::CMF_YEAR): return QVariant(startList.at(index.row()).getYear()); + case static_cast(Competitor::Field::CMF_CLUB): + return QVariant(startList.at(index.row()).getClub()); case static_cast(Competitor::Field::CMF_TEAM): return QVariant(startList.at(index.row()).getTeam()); case static_cast(Competitor::Field::CMF_OFFSET_LEG): @@ -122,6 +148,8 @@ QVariant StartListModel::data(QModelIndex const &index, int role) const return QVariant(tr("Male (M) or Female (F)")); case static_cast(Competitor::Field::CMF_YEAR): return QVariant(tr("Year of birth (i.e. 1982)")); + case static_cast(Competitor::Field::CMF_CLUB): + return QVariant(tr("Club name")); case static_cast(Competitor::Field::CMF_TEAM): return QVariant(tr("Team name")); case static_cast(Competitor::Field::CMF_OFFSET_LEG): @@ -150,6 +178,7 @@ bool StartListModel::setData(QModelIndex const &index, QVariant const &value, in if (retval && uval) { int maxLeg = this->getMaxLeg(uval, index.row()); startList[index.row()].setBib(uval); + startList[index.row()].setClub(this->getClub(uval)); startList[index.row()].setTeam(this->getTeam(uval)); startList[index.row()].setOffset((maxLeg < 0) ? &maxLeg : Q_NULLPTR); } else { @@ -174,6 +203,16 @@ bool StartListModel::setData(QModelIndex const &index, QVariant const &value, in uval = value.toUInt(&retval); if (retval) startList[index.row()].setYear(uval); break; + case static_cast(Competitor::Field::CMF_CLUB): + uval = startList[index.row()].getBib(); + if (uval == 0) { + startList[index.row()].setClub(value.toString().simplified()); + } else { + this->setClub(uval, value.toString().simplified()); + } + emit newClub(startList[index.row()].getClub()); + retval = true; + break; case static_cast(Competitor::Field::CMF_TEAM): uval = startList[index.row()].getBib(); if (uval == 0) { @@ -181,7 +220,6 @@ bool StartListModel::setData(QModelIndex const &index, QVariant const &value, in } else { this->setTeam(uval, value.toString().simplified()); } - emit newTeam(startList[index.row()].getTeam()); retval = true; break; case static_cast(Competitor::Field::CMF_OFFSET_LEG): @@ -213,6 +251,8 @@ QVariant StartListModel::headerData(int section, Qt::Orientation orientation, in return QString("%1").arg(tr("Sex")); case static_cast(Competitor::Field::CMF_YEAR): return QString("%1").arg(tr("Year")); + case static_cast(Competitor::Field::CMF_CLUB): + return QString("%1").arg(tr("Club")); case static_cast(Competitor::Field::CMF_TEAM): return QString("%1").arg(tr("Team")); case static_cast(Competitor::Field::CMF_OFFSET_LEG): @@ -274,7 +314,8 @@ void StartListModel::reset() startList.clear(); legCount = 0; maxBib = 0; - competitorNameMaxWidth = 0; + competitorNameWidthMax = 0; + teamNameWidthMax = 0; endResetModel(); } @@ -299,9 +340,23 @@ uint StartListModel::getMaxBib() const return maxBib; } -uint StartListModel::getCompetitorNameMaxWidth() const +uint StartListModel::getCompetitorNameWidthMax() const +{ + return competitorNameWidthMax; +} + +uint StartListModel::getTeamNameWidthMax() const { - return competitorNameMaxWidth; + return teamNameWidthMax; +} + +QString const *StartListModel::getClub(uint bib) +{ + for (qsizetype row = 0; row < startList.count(); row++) + if (startList[row].getBib() == bib) + return &startList[row].getClub(); + + return Q_NULLPTR; } QString const *StartListModel::getTeam(uint bib) @@ -313,6 +368,13 @@ QString const *StartListModel::getTeam(uint bib) return Q_NULLPTR; } +void StartListModel::setClub(uint bib, QString const &club) +{ + for (qsizetype row = 0; row < startList.count(); row++) + if (startList[row].getBib() == bib) + startList[row].setClub(club); +} + void StartListModel::setTeam(uint bib, QString const &team) { for (qsizetype row = 0; row < startList.count(); row++) diff --git a/startlistmodel.hpp b/startlistmodel.hpp index e9aa0d3..dc0d1be 100644 --- a/startlistmodel.hpp +++ b/startlistmodel.hpp @@ -52,22 +52,26 @@ class StartListModel : public CRTableModel uint getLegCount() const; void setLegCount(uint leg); uint getMaxBib() const; - uint getCompetitorNameMaxWidth() const; + uint getCompetitorNameWidthMax() const; + uint getTeamNameWidthMax() const; public slots: void refreshCounters(int r) override; signals: - void newTeam(QString const &team); + void newClub(QString const &club); void error(QString const &message); private: QList startList; uint legCount; uint maxBib; - uint competitorNameMaxWidth; + uint competitorNameWidthMax; + uint teamNameWidthMax; + QString const *getClub(uint bib); QString const *getTeam(uint bib); + void setClub(uint bib, QString const &club); void setTeam(uint bib, QString const &team); int getMaxLeg(uint bib, int skip); }; diff --git a/teamclassentry.cpp b/teamclassentry.cpp index a6f20b7..1222ce9 100644 --- a/teamclassentry.cpp +++ b/teamclassentry.cpp @@ -18,9 +18,9 @@ #include "teamclassentry.hpp" #include "lbcrexception.hpp" -QString const &TeamClassEntry::getTeam() const +QString const &TeamClassEntry::getClub() const { - return team; + return club; } ClassEntry const *TeamClassEntry::getClassEntry(int index) const @@ -34,9 +34,9 @@ ClassEntry const *TeamClassEntry::getClassEntry(int index) const void TeamClassEntry::setClassEntry(ClassEntry *entry) { if (this->entryList.isEmpty()) { - this->team = entry->getTeam(); - } else if (this->team.compare(entry->getTeam()) != 0) { - throw(ChronoRaceException(tr("Unexpected team: expected %1 - found %2").arg(this->team, entry->getTeam()))); + this->club = entry->getClub(); + } else if (this->club.compare(entry->getClub()) != 0) { + throw(ChronoRaceException(tr("Unexpected club: expected %1 - found %2").arg(this->club, entry->getClub()))); } this->entryList.push_back(entry); } diff --git a/teamclassentry.hpp b/teamclassentry.hpp index 987b2b6..ff9b322 100644 --- a/teamclassentry.hpp +++ b/teamclassentry.hpp @@ -31,11 +31,11 @@ class TeamClassEntry Q_DECLARE_TR_FUNCTIONS(TeamClassEntry) private: - QString team { "" }; + QString club { "" }; QVector entryList { }; public: - QString const &getTeam() const; + QString const &getClub() const; ClassEntry const *getClassEntry(int index) const; void setClassEntry(ClassEntry *entry); int getClassEntryCount() const; diff --git a/teamslistmodel.cpp b/teamslistmodel.cpp index 3b50a80..5559534 100644 --- a/teamslistmodel.cpp +++ b/teamslistmodel.cpp @@ -21,36 +21,27 @@ QDataStream &operator<<(QDataStream &out, TeamsListModel const &data) { + quint32 v2TeamNameWidthMax = 0; + out << data.teamsList - << quint32(data.teamNameWidthMax); + << quint32(v2TeamNameWidthMax); return out; } QDataStream &operator>>(QDataStream &in, TeamsListModel &data) { - quint32 teamNameWidthMax; + quint32 v2TeamNameWidthMax; in >> data.teamsList - >> teamNameWidthMax; - - data.teamNameWidthMax = teamNameWidthMax; + >> v2TeamNameWidthMax; return in; } void TeamsListModel::refreshCounters(int r) { - uint teamNameLength; - Q_UNUSED(r) - - teamNameWidthMax = 0; - for (auto const &team : teamsList) { - teamNameLength = static_cast(team.length()); - if (teamNameLength > teamNameWidthMax) - teamNameWidthMax = teamNameLength; - } } int TeamsListModel::rowCount(QModelIndex const &parent) const @@ -78,7 +69,7 @@ QVariant TeamsListModel::data(QModelIndex const &index, int role) const if (role == Qt::DisplayRole) return QVariant(teamsList.at(index.row())); else if (role == Qt::ToolTipRole) - return QVariant(tr("Team name")); + return QVariant(tr("Club name")); else return QVariant(); } @@ -90,7 +81,7 @@ QVariant TeamsListModel::headerData(int section, Qt::Orientation orientation, in return QVariant(); if (orientation == Qt::Horizontal) - return QString("%1").arg(tr("Team Name")); + return QString("%1").arg(tr("Club Name")); else return QString("%1").arg(section + 1); } @@ -154,7 +145,6 @@ void TeamsListModel::sort(int column, Qt::SortOrder order) void TeamsListModel::reset() { beginResetModel(); teamsList.clear(); - teamNameWidthMax = 0; endResetModel(); } @@ -164,18 +154,9 @@ void TeamsListModel::addTeam(QString const &team) int rowCount = this->rowCount(); this->insertRow(rowCount, QModelIndex()); this->setData(this->index(rowCount, 0, QModelIndex()), QVariant(team), Qt::EditRole); - - auto teamNameLength = static_cast(team.length()); - if (teamNameLength > teamNameWidthMax) - teamNameWidthMax = teamNameLength; } } -uint TeamsListModel::getTeamNameWidthMax() const -{ - return teamNameWidthMax; -} - QList const &TeamsListModel::getTeamsList() const { return teamsList; diff --git a/teamslistmodel.hpp b/teamslistmodel.hpp index da5533e..26e1dea 100644 --- a/teamslistmodel.hpp +++ b/teamslistmodel.hpp @@ -48,15 +48,12 @@ class TeamsListModel : public CRTableModel void reset(); - uint getTeamNameWidthMax() const; - public slots: void addTeam(QString const &team); void refreshCounters(int r) override; private: QList teamsList; - uint teamNameWidthMax; }; #endif // LBTEAMSLISTMODEL_H diff --git a/translations/LBChronoRace_en.ts b/translations/LBChronoRace_en.ts index 05e9c50..30271ee 100644 --- a/translations/LBChronoRace_en.ts +++ b/translations/LBChronoRace_en.ts @@ -497,10 +497,6 @@ RESET RESET - - Timer controls are disabled when checked - Timer controls are disabled when checked - LOCK LOCK @@ -561,6 +557,10 @@ Continue? All recorded timings and bibs will be deleted. Continue? + + Timer controls are disabled when locked + Timer controls are disabled when locked + ClassEntry @@ -595,8 +595,8 @@ Continue? Edit Race Information - Edit Teams List - Edit Teams List + View Clubs List + View Clubs List Teams @@ -706,10 +706,6 @@ Continue? S S - - Te&ams - Te&ams - About LBChronoRace About LBChronoRace @@ -735,8 +731,8 @@ Continue? Start List - Teams List - Teams List + Clubs List + Clubs List Timings List @@ -807,8 +803,8 @@ Continue? Start List File saved: %1 - Select Teams List - Select Teams List + Select Clubs List + Select Clubs List Teams File saved: %1 @@ -870,10 +866,6 @@ Continue? Edit race information, including logos Edit race information, including logos - - See the list of the teams (that cannot be changed) - See the list of the teams (that cannot be changed) - Add, remove, and change the race timings Add, remove, and change the race timings @@ -918,6 +910,14 @@ Continue? Save current race data to a new file Save current race data to a new file + + See the list of the clubs (that cannot be changed) + See the list of the clubs (that cannot be changed) + + + Cl&ubs + Cl&ubs + PDFRankingPrinter @@ -1319,6 +1319,14 @@ Continue? Start time/Leg Start time/Leg + + Club name + Club name + + + Club + Club + TXTRankingPrinter @@ -1357,19 +1365,19 @@ Continue? Requested index %1 exceeds the number of available entries %2 - Unexpected team: expected %1 - found %2 - Unexpected team: expected %1 - found %2 + Unexpected club: expected %1 - found %2 + Unexpected club: expected %1 - found %2 TeamsListModel - Team name - Team name + Club name + Club name - Team Name - Team Name + Club Name + Club Name diff --git a/translations/LBChronoRace_it.ts b/translations/LBChronoRace_it.ts index 0a55924..18dea5f 100644 --- a/translations/LBChronoRace_it.ts +++ b/translations/LBChronoRace_it.ts @@ -497,10 +497,6 @@ RESET AZZERA - - Timer controls are disabled when checked - Disabilita i pulsanti di controllo del cronometro - LOCK BLOCCA @@ -561,6 +557,10 @@ Continue? Tutti i tempi registrati e i pettorali saranno cancellati. Continuare? + + Timer controls are disabled when locked + Disabilita i pulsanti di controllo del cronometro + ClassEntry @@ -595,8 +595,8 @@ Continuare? Modifica Informazioni Gara - Edit Teams List - Modifica Lista Squadre + View Clubs List + Visualizza Lista Società Teams @@ -706,10 +706,6 @@ Continuare? S S - - Te&ams - Squ&adre - About LBChronoRace Informazioni su LBChronoRace @@ -735,8 +731,8 @@ Continuare? Ordine di Partenza - Teams List - Lista Squadre + Clubs List + Lista Società Timings List @@ -807,8 +803,8 @@ Continuare? File Ordine di Partenza salvato: %1 - Select Teams List - Seleziona Lista Squadre + Select Clubs List + Seleziona Clubs Squadre Teams File saved: %1 @@ -870,10 +866,6 @@ Continuare? Edit race information, including logos Modifica le informazioni sulla gara, compresi i loghi - - See the list of the teams (that cannot be changed) - Visualizza l'elenco delle squadre (che non può essere modificato) - Add, remove, and change the race timings Aggiunge, rimuove e modifica i tempi di gara @@ -918,6 +910,14 @@ Continuare? Save current race data to a new file Salva i dati di gara in un nuovo file + + See the list of the clubs (that cannot be changed) + Visualizza l'elenco delle società (che non può essere modificato) + + + Cl&ubs + &Società + PDFRankingPrinter @@ -1319,6 +1319,14 @@ Continuare? Start time/Leg Partenza/Frazione + + Club name + Nome società + + + Club + Società + TXTRankingPrinter @@ -1357,19 +1365,19 @@ Continuare? L'elemento richiesto %1 supera il numero di elementi disponibili %2 - Unexpected team: expected %1 - found %2 - Squadra non valida: attesa %1 - trovata %2 + Unexpected club: expected %1 - found %2 + Società non valida: attesa %1 - trovata %2 TeamsListModel - Team name - Nome squadra + Club name + Nome società - Team Name - Nome Squadra + Club Name + Nome Società diff --git a/txtrankingprinter.cpp b/txtrankingprinter.cpp index 326d4b2..4a3ea5f 100644 --- a/txtrankingprinter.cpp +++ b/txtrankingprinter.cpp @@ -128,7 +128,7 @@ void TXTRankingPrinter::printRanking(const Category &category, QListgetTotalTimeTxt(); + currTime = c->getTotalTime(CRLoader::Format::TEXT); if ((currPosNumber = position.getCurrentPositionNumber(i, currTime)) == 0) currPosNumber = prevPosNumber; else @@ -143,10 +143,10 @@ void TXTRankingPrinter::printRanking(const Category &category, QListgetBib(); txtStream.setFieldWidth(0); txtStream << " - "; - txtStream << c->getNamesTxt(); + txtStream << c->getNames(CRLoader::Format::TEXT); txtStream << " - "; if (CRLoader::getStartListLegs() > 1) - txtStream << c->getTimesTxt(getIndexFieldWidth()) << " - "; + txtStream << c->getTimes(CRLoader::Format::TEXT, getIndexFieldWidth()) << " - "; txtStream << currTime << Qt::endl; } txtStream << Qt::endl; @@ -180,11 +180,11 @@ void TXTRankingPrinter::printRanking(const Category &category, QListgetClassEntry(j)->getBib(); txtStream.setFieldWidth(0); txtStream << " - "; - txtStream << r->getClassEntry(j)->getNamesTxt(); + txtStream << r->getClassEntry(j)->getNames(CRLoader::Format::TEXT); txtStream << " - "; if (CRLoader::getStartListLegs() > 1) - txtStream << r->getClassEntry(j)->getTimesTxt(getIndexFieldWidth()) << " - "; - txtStream << r->getClassEntry(j)->getTotalTimeTxt() << Qt::endl; + txtStream << r->getClassEntry(j)->getTimes(CRLoader::Format::TEXT, getIndexFieldWidth()) << " - "; + txtStream << r->getClassEntry(j)->getTotalTime(CRLoader::Format::TEXT) << Qt::endl; } txtStream << Qt::endl; } From 49f6a6c45c30db2e10bde177a59165db460ba05d Mon Sep 17 00:00:00 2001 From: Lorenzo Buzzi Date: Sat, 29 Jun 2024 00:32:22 +0200 Subject: [PATCH 2/5] Encoding selection when importing CSV data The user can now choose between ISO-8859-1 and UTF-8 when is about to import CSV data. --- chronoracetable.cpp | 11 ++++++++++- chronoracetable.hpp | 3 ++- lbchronorace.cpp | 13 +++++++------ lbchronorace.hpp | 7 ++++--- translations/LBChronoRace_en.ts | 20 ++++++++++++++++---- translations/LBChronoRace_it.ts | 22 +++++++++++++++++----- 6 files changed, 56 insertions(+), 20 deletions(-) diff --git a/chronoracetable.cpp b/chronoracetable.cpp index d94e4fd..b3cb1a5 100644 --- a/chronoracetable.cpp +++ b/chronoracetable.cpp @@ -15,6 +15,8 @@ * along with this program. If not, see . * *****************************************************************************/ +#include + #include "chronoracetable.hpp" ChronoRaceTable::ChronoRaceTable(QWidget *parent) : QDialog(parent) @@ -88,7 +90,14 @@ void ChronoRaceTable::rowDel() const void ChronoRaceTable::modelImport() { - emit modelImported(); + if (QMessageBox::question(this, tr("CSV Encoding"), + tr("Are the data you are importing ISO-8859-1 (Latin-1) encoded?\n" + "Choose No to use UTF-8 encoding. If in doubt, choose Yes."), + QMessageBox::No | QMessageBox::Yes, QMessageBox::Yes) == QMessageBox::Yes) { + emit modelImported(CRLoader::Encoding::LATIN1); + } else { + emit modelImported(CRLoader::Encoding::UTF8); + } } void ChronoRaceTable::modelExport() diff --git a/chronoracetable.hpp b/chronoracetable.hpp index d2accf3..acc35b7 100644 --- a/chronoracetable.hpp +++ b/chronoracetable.hpp @@ -21,6 +21,7 @@ #include #include "ui_chronoracetable.h" +#include "crloader.hpp" #include "crtablemodel.hpp" class ChronoRaceTable : public QDialog @@ -46,7 +47,7 @@ public slots: signals: void newRowCount(int count); - void modelImported(); + void modelImported(CRLoader::Encoding encoding); void modelExported(); void countersRefresh(); diff --git a/lbchronorace.cpp b/lbchronorace.cpp index 649e63b..a90968e 100644 --- a/lbchronorace.cpp +++ b/lbchronorace.cpp @@ -26,8 +26,6 @@ //NOSONAR #include #include "lbchronorace.hpp" -#include "crloader.hpp" -#include "crloader.hpp" #include "lbcrexception.hpp" #include "rankingswizard.hpp" @@ -150,7 +148,7 @@ void LBChronoRace::appendErrorMessage(QString const &message) const ui->errorDisplay->appendPlainText(message); } -void LBChronoRace::importStartList() +void LBChronoRace::importStartList(CRLoader::Encoding encoding) { startListFileName = QFileDialog::getOpenFileName(this, tr("Select Start List"), lastSelectedPath.absolutePath(), tr("CSV (*.csv)")); @@ -159,6 +157,7 @@ void LBChronoRace::importStartList() QPair count(0, 0); appendInfoMessage(tr("Start List File: %1").arg(startListFileName)); try { + CRLoader::setEncoding(encoding); count = CRLoader::importStartList(startListFileName); appendInfoMessage(tr("Loaded: %n competitor(s)", "", count.first)); appendInfoMessage(tr("Loaded: %n team(s)", "", count.second)); @@ -171,7 +170,7 @@ void LBChronoRace::importStartList() } } -void LBChronoRace::importCategoriesList() +void LBChronoRace::importCategoriesList(CRLoader::Encoding encoding) { categoriesFileName = QFileDialog::getOpenFileName(this, tr("Select Categories File"), lastSelectedPath.absolutePath(), tr("CSV (*.csv)")); @@ -180,6 +179,7 @@ void LBChronoRace::importCategoriesList() int count = 0; appendInfoMessage(tr("Categories File: %1").arg(categoriesFileName)); try { + CRLoader::setEncoding(encoding); count = CRLoader::importCategories(categoriesFileName); appendInfoMessage(tr("Loaded: %n category(s)", "", count)); lastSelectedPath = QFileInfo(categoriesFileName).absoluteDir(); @@ -190,7 +190,7 @@ void LBChronoRace::importCategoriesList() } } -void LBChronoRace::importTimingsList() +void LBChronoRace::importTimingsList(CRLoader::Encoding encoding) { timingsFileName = QFileDialog::getOpenFileName(this, tr("Select Timings File"), lastSelectedPath.absolutePath(), tr("CSV (*.csv)")); @@ -199,6 +199,7 @@ void LBChronoRace::importTimingsList() int count = 0; appendInfoMessage(tr("Timings File: %1").arg(timingsFileName)); try { + CRLoader::setEncoding(encoding); count = CRLoader::importTimings(timingsFileName); appendInfoMessage(tr("Loaded: %n timing(s)", "", count)); lastSelectedPath = QFileInfo(timingsFileName).absoluteDir(); @@ -420,7 +421,7 @@ bool LBChronoRace::loadRaceFile(QString const &fileName) retval = true; break; default: - QMessageBox::information(this, tr("Race Data File Error"), tr("Format version %1 not supported").arg(binFmt)); + QMessageBox::information(this, tr("Race Data File Error"), tr("Data format %1 not supported.\nPlease uodate the application.").arg(binFmt)); break; } } else { diff --git a/lbchronorace.hpp b/lbchronorace.hpp index 7b5d64f..3832907 100644 --- a/lbchronorace.hpp +++ b/lbchronorace.hpp @@ -25,6 +25,7 @@ #include "ui_chronorace.h" +#include "crloader.hpp" #include "chronoracetable.hpp" #include "chronoracedata.hpp" #include "chronoracetimings.hpp" @@ -102,9 +103,9 @@ private slots: void makeStartList(); void makeRankings(); - void importStartList(); - void importCategoriesList(); - void importTimingsList(); + void importStartList(CRLoader::Encoding encoding); + void importCategoriesList(CRLoader::Encoding encoding); + void importTimingsList(CRLoader::Encoding encoding); void exportStartList(); void exportTeamList(); diff --git a/translations/LBChronoRace_en.ts b/translations/LBChronoRace_en.ts index 30271ee..33d337e 100644 --- a/translations/LBChronoRace_en.ts +++ b/translations/LBChronoRace_en.ts @@ -454,6 +454,16 @@ Quit Quit + + Are the data you are importing ISO-8859-1 (Latin-1) encoded? +Choose No to use UTF-8 encoding. If in doubt, choose Yes. + Are the data you are importing ISO-8859-1 (Latin-1) encoded? +Choose No to use UTF-8 encoding. If in doubt, choose Yes. + + + CSV Encoding + CSV Encoding + ChronoRaceTimings @@ -842,10 +852,6 @@ Continue? Race Data File Error Race Data File Error - - Format version %1 not supported - Format version %1 not supported - Race saved: %1 Race saved: %1 @@ -918,6 +924,12 @@ Continue? Cl&ubs Cl&ubs + + Data format %1 not supported. +Please uodate the application. + Data format %1 not supported. +Please uodate the application. + PDFRankingPrinter diff --git a/translations/LBChronoRace_it.ts b/translations/LBChronoRace_it.ts index 18dea5f..c1f04ee 100644 --- a/translations/LBChronoRace_it.ts +++ b/translations/LBChronoRace_it.ts @@ -454,6 +454,16 @@ Quit Esci + + Are the data you are importing ISO-8859-1 (Latin-1) encoded? +Choose No to use UTF-8 encoding. If in doubt, choose Yes. + I dati che si stanno per importare sono codificati ISO-8859-1 (Latin-1)? +Sceglire No per usare la codifica UTF-8. Nel dubbio, scegliere Si. + + + CSV Encoding + Codifica CSV + ChronoRaceTimings @@ -840,11 +850,7 @@ Continuare? Race Data File Error - Errore File Gara - - - Format version %1 not supported - Formato versione %1 non supportato + Errore File Dati Gara Race saved: %1 @@ -918,6 +924,12 @@ Continuare? Cl&ubs &Società + + Data format %1 not supported. +Please uodate the application. + Formato dati %1 non supportato. +Aggiornare l'applicazione. + PDFRankingPrinter From 64b3312ad54fb67a21893de69a43bf82503f4a48 Mon Sep 17 00:00:00 2001 From: Lorenzo Buzzi Date: Mon, 1 Jul 2024 07:46:47 +0200 Subject: [PATCH 3/5] Club selection in a drop-down list when entering Competitors --- CMakeLists.txt | 2 + chronorace.ui | 2 +- chronoracetable.cpp | 5 +++ chronoracetable.hpp | 1 + clubdelegate.cpp | 66 +++++++++++++++++++++++++++++++++ clubdelegate.hpp | 42 +++++++++++++++++++++ crloader.cpp | 5 +++ crloader.hpp | 2 + lbchronorace.cpp | 9 ++++- lbchronorace.hpp | 3 ++ translations/LBChronoRace_en.ts | 4 ++ translations/LBChronoRace_it.ts | 4 ++ 12 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 clubdelegate.cpp create mode 100644 clubdelegate.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d739a4..01dd513 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,6 +67,8 @@ set(PROJECT_SOURCES chronoracetimings.ui classentry.cpp classentry.hpp + clubdelegate.cpp + clubdelegate.hpp competitor.cpp competitor.hpp crloader.cpp diff --git a/chronorace.ui b/chronorace.ui index b0bfcd9..d12a3c8 100644 --- a/chronorace.ui +++ b/chronorace.ui @@ -80,7 +80,7 @@ - Teams + Clubs Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter diff --git a/chronoracetable.cpp b/chronoracetable.cpp index b3cb1a5..2baa859 100644 --- a/chronoracetable.cpp +++ b/chronoracetable.cpp @@ -54,6 +54,11 @@ void ChronoRaceTable::disableButtons() const //ui->modelExport->setEnabled(false); //NOSONAR } +void ChronoRaceTable::setItemDelegateForColumn(int column, QAbstractItemDelegate *delegate) +{ + ui->tableView->setItemDelegateForColumn(column, delegate); +} + void ChronoRaceTable::show() { ui->retranslateUi(this); diff --git a/chronoracetable.hpp b/chronoracetable.hpp index acc35b7..4630356 100644 --- a/chronoracetable.hpp +++ b/chronoracetable.hpp @@ -34,6 +34,7 @@ class ChronoRaceTable : public QDialog QAbstractTableModel *getModel() const; void setModel(CRTableModel *model) const; void disableButtons() const; + void setItemDelegateForColumn(int column, QAbstractItemDelegate *delegate); private slots: void rowAdd() const; diff --git a/clubdelegate.cpp b/clubdelegate.cpp new file mode 100644 index 0000000..34ad582 --- /dev/null +++ b/clubdelegate.cpp @@ -0,0 +1,66 @@ +/***************************************************************************** + * Copyright (C) 2021 by Lorenzo Buzzi (lorenzo@buzzi.pro) * + * * + * 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 3 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ + +#include "clubdelegate.hpp" +#include "crloader.hpp" + +ClubDelegate::ClubDelegate(QObject *parent) : + QStyledItemDelegate(parent) +{ + auto *comboBox = box.data(); + comboBox->setEditable(true); + comboBox->setInsertPolicy(QComboBox::InsertAlphabetically); + comboBox->setDuplicatesEnabled(false); + comboBox->addItems(CRLoader::getClubs()); +} + +QWidget *ClubDelegate::createEditor(QWidget *parent, QStyleOptionViewItem const &option, QModelIndex const &index) const +{ + Q_UNUSED(option) + Q_UNUSED(index) + + auto *comboBox = box.data(); + comboBox->setParent(parent); + + return comboBox; +} + +void ClubDelegate::destroyEditor(QWidget *editor, const QModelIndex &index) const +{ + Q_UNUSED(editor) + Q_UNUSED(index) +} + +void ClubDelegate::setEditorData(QWidget *editor, QModelIndex const &index) const +{ + // Get the value via index of the Model and put it into the ComboBox + auto *comboBox = static_cast(editor); + comboBox->setCurrentText(index.model()->data(index, Qt::EditRole).toString()); +} + +void ClubDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, QModelIndex const &index) const +{ + auto const *comboBox = static_cast(editor); + model->setData(index, comboBox->currentData(Qt::EditRole), Qt::EditRole); +} + +void ClubDelegate::updateEditorGeometry(QWidget *editor, QStyleOptionViewItem const &option, QModelIndex const &index) const +{ + Q_UNUSED(index) + + editor->setGeometry(option.rect); +} diff --git a/clubdelegate.hpp b/clubdelegate.hpp new file mode 100644 index 0000000..90abfde --- /dev/null +++ b/clubdelegate.hpp @@ -0,0 +1,42 @@ +/***************************************************************************** + * Copyright (C) 2021 by Lorenzo Buzzi (lorenzo@buzzi.pro) * + * * + * 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 3 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ + +#ifndef CLUBDELEGATE_HPP +#define CLUBDELEGATE_HPP + +#include +#include +#include +#include + +class ClubDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + explicit ClubDelegate(QObject *parent = Q_NULLPTR); + + QWidget *createEditor(QWidget *parent, QStyleOptionViewItem const &option, QModelIndex const &index) const override; + void destroyEditor(QWidget *editor, const QModelIndex &index) const override; + void setEditorData(QWidget *editor, QModelIndex const &index) const override; + void setModelData(QWidget *editor, QAbstractItemModel *model, QModelIndex const &index) const override; + void updateEditorGeometry(QWidget *editor, QStyleOptionViewItem const &option, QModelIndex const &index) const override; + +private: + QScopedPointer box { new QComboBox }; +}; + +#endif // CLUBDELEGATE_HPP diff --git a/crloader.cpp b/crloader.cpp index 73fc166..a58ecb1 100644 --- a/crloader.cpp +++ b/crloader.cpp @@ -51,6 +51,11 @@ CRTableModel *CRLoader::getCategoriesModel() return &categoriesModel; } +QStringList CRLoader::getClubs() +{ + return QStringList(teamsListModel.getTeamsList()); +} + CRLoader::Encoding CRLoader::getEncoding() { return encoding; diff --git a/crloader.hpp b/crloader.hpp index 38b2ff1..e6ab5c1 100644 --- a/crloader.hpp +++ b/crloader.hpp @@ -98,6 +98,8 @@ class CRLoader static Format getFormat(); static void setFormat(Format const &value); static QString formatToLabel(Format const &value); + + static QStringList getClubs(); }; #endif // LBLOADER_H diff --git a/lbchronorace.cpp b/lbchronorace.cpp index a90968e..ab0ed1c 100644 --- a/lbchronorace.cpp +++ b/lbchronorace.cpp @@ -39,7 +39,8 @@ LBChronoRace::LBChronoRace(QWidget *parent, QGuiApplication const *app) : startListTable(parent), teamsTable(parent), categoriesTable(parent), - timingsTable(parent) + timingsTable(parent), + clubDelegate(&startListTable) { startListFileName = lastSelectedPath.filePath(LBCHRONORACE_STARTLIST_DEFAULT); timingsFileName = lastSelectedPath.filePath(LBCHRONORACE_TIMINGS_DEFAULT); @@ -116,6 +117,9 @@ LBChronoRace::LBChronoRace(QWidget *parent, QGuiApplication const *app) : QObject::connect(ui->actionAbout, &QAction::triggered, this, &LBChronoRace::actionAbout); QObject::connect(ui->actionAboutQt, &QAction::triggered, this, &LBChronoRace::actionAboutQt); + + // tie the views with the related delegate instances + startListTable.setItemDelegateForColumn(static_cast(Competitor::Field::CMF_CLUB), &clubDelegate); } void LBChronoRace::setCounterTeams(int count) const @@ -126,6 +130,9 @@ void LBChronoRace::setCounterTeams(int count) const void LBChronoRace::setCounterCompetitors(int count) const { ui->counterCompetitors->display(count); + + // also update the counter for the list of clubs + setCounterTeams(CRLoader::getTeamsListModel()->rowCount()); } void LBChronoRace::setCounterCategories(int count) const diff --git a/lbchronorace.hpp b/lbchronorace.hpp index 3832907..741f20d 100644 --- a/lbchronorace.hpp +++ b/lbchronorace.hpp @@ -29,6 +29,7 @@ #include "chronoracetable.hpp" #include "chronoracedata.hpp" #include "chronoracetimings.hpp" +#include "clubdelegate.hpp" #ifndef LBCHRONORACE_NAME #error "LBCHRONORACE_NAME not set" @@ -88,6 +89,8 @@ public slots: ChronoRaceTimings timings; + ClubDelegate clubDelegate; + bool loadRaceFile(QString const &fileName); private slots: diff --git a/translations/LBChronoRace_en.ts b/translations/LBChronoRace_en.ts index 33d337e..575983f 100644 --- a/translations/LBChronoRace_en.ts +++ b/translations/LBChronoRace_en.ts @@ -930,6 +930,10 @@ Please uodate the application. Data format %1 not supported. Please uodate the application. + + Clubs + Clubs + PDFRankingPrinter diff --git a/translations/LBChronoRace_it.ts b/translations/LBChronoRace_it.ts index c1f04ee..18ab1c4 100644 --- a/translations/LBChronoRace_it.ts +++ b/translations/LBChronoRace_it.ts @@ -930,6 +930,10 @@ Please uodate the application. Formato dati %1 non supportato. Aggiornare l'applicazione. + + Clubs + Società + PDFRankingPrinter From 37d2e2bd20918195e07f9b2edaf406a5a2cd4fc5 Mon Sep 17 00:00:00 2001 From: Lorenzo Buzzi Date: Mon, 1 Jul 2024 15:51:59 +0200 Subject: [PATCH 4/5] Other selections in drop-down lists when entering data - Sex for Competitor - Sex for Category - Type for Category --- CMakeLists.txt | 6 +++ categoriesmodel.cpp | 2 +- category.cpp | 22 +++++++++ category.hpp | 9 ++++ catsexdelegate.cpp | 86 +++++++++++++++++++++++++++++++++ catsexdelegate.hpp | 46 ++++++++++++++++++ cattypedelegate.cpp | 79 ++++++++++++++++++++++++++++++ cattypedelegate.hpp | 46 ++++++++++++++++++ icons/agender.svg | 1 + icons/female.svg | 1 + icons/group.svg | 1 + icons/male.svg | 1 + icons/person.svg | 1 + icons/transgender.svg | 1 + icons/unknown_med.svg | 1 + lbchronorace.cpp | 8 ++- lbchronorace.hpp | 6 +++ materialicons.qrc | 7 +++ sexdelegate.cpp | 83 +++++++++++++++++++++++++++++++ sexdelegate.hpp | 46 ++++++++++++++++++ startlistmodel.cpp | 2 +- translations/LBChronoRace_en.ts | 77 ++++++++++++++++++++++++++--- translations/LBChronoRace_it.ts | 77 ++++++++++++++++++++++++++--- 23 files changed, 590 insertions(+), 19 deletions(-) create mode 100644 catsexdelegate.cpp create mode 100644 catsexdelegate.hpp create mode 100644 cattypedelegate.cpp create mode 100644 cattypedelegate.hpp create mode 100644 icons/agender.svg create mode 100644 icons/female.svg create mode 100644 icons/group.svg create mode 100644 icons/male.svg create mode 100644 icons/person.svg create mode 100644 icons/transgender.svg create mode 100644 icons/unknown_med.svg create mode 100644 sexdelegate.cpp create mode 100644 sexdelegate.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 01dd513..edf70cc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,6 +53,10 @@ set(PROJECT_SOURCES categoriesmodel.hpp category.cpp category.hpp + catsexdelegate.cpp + catsexdelegate.hpp + cattypedelegate.cpp + cattypedelegate.hpp chronorace.ui chronoracedata.cpp chronoracedata.hpp @@ -94,6 +98,8 @@ set(PROJECT_SOURCES rankingswizardmode.hpp rankingswizardselection.cpp rankingswizardselection.hpp + sexdelegate.cpp + sexdelegate.hpp startlistmodel.cpp startlistmodel.hpp teamclassentry.cpp diff --git a/categoriesmodel.cpp b/categoriesmodel.cpp index e0041a9..8a0a5b3 100644 --- a/categoriesmodel.cpp +++ b/categoriesmodel.cpp @@ -83,7 +83,7 @@ QVariant CategoriesModel::data(QModelIndex const &index, int role) const case static_cast(Category::Field::CTF_TEAM): return QVariant(tr("Individual (I) or Team (T)")); case static_cast(Category::Field::CTF_SEX): - return QVariant(tr("Male (M), Female (F), Misc (X) or Unspecified (U)")); + return QVariant(tr("Men (M), Women (F), Mixed (X) or All (U)")); case static_cast(Category::Field::CTF_TO_YEAR): return QVariant(tr("The category will include competitors born up to and including this year (i.e. 2000); 0 to disable")); case static_cast(Category::Field::CTF_FROM_YEAR): diff --git a/category.cpp b/category.cpp index 64bedc9..f2f4c90 100644 --- a/category.cpp +++ b/category.cpp @@ -64,6 +64,28 @@ QDataStream &operator>>(QDataStream &in, Category &category) return in; } +Category::Type Category::toType(QString const &type) +{ + if (type.compare("I", Qt::CaseInsensitive) == 0) + return Type::INDIVIDUAL; + else if (type.compare("T", Qt::CaseInsensitive) == 0) + return Type::CLUB; + else + throw(ChronoRaceException(tr("Illegal type '%1'").arg(type))); +} + +QString Category::toTypeString(Type const type) +{ + switch (type) { + case Type::INDIVIDUAL: + return "I"; + case Type::CLUB: + return "T"; + default: + throw(ChronoRaceException(tr("Unexpected Type enum value '%1'").arg(static_cast(type)))); + } +} + bool Category::isTeam() const { return team; diff --git a/category.hpp b/category.hpp index 0513290..9de5545 100644 --- a/category.hpp +++ b/category.hpp @@ -31,6 +31,12 @@ class Category { Q_DECLARE_TR_FUNCTIONS(Category) public: + enum class Type + { + INDIVIDUAL, + CLUB, + }; + enum class Field { CTF_FIRST = 0, @@ -59,6 +65,9 @@ class Category { friend QDataStream &operator<<(QDataStream &out, Category const &category); friend QDataStream &operator>>(QDataStream &in, Category &category); + static Type toType(QString const &type); + static QString toTypeString(Type const type); + bool isTeam() const; void setTeam(bool newTeam); uint getFromYear() const; diff --git a/catsexdelegate.cpp b/catsexdelegate.cpp new file mode 100644 index 0000000..e481a72 --- /dev/null +++ b/catsexdelegate.cpp @@ -0,0 +1,86 @@ +/***************************************************************************** + * Copyright (C) 2021 by Lorenzo Buzzi (lorenzo@buzzi.pro) * + * * + * 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 3 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ + +#include "catsexdelegate.hpp" +#include "lbcrexception.hpp" + +CategorySexDelegate::CategorySexDelegate(QObject *parent) : + QStyledItemDelegate(parent) +{ + auto *comboBox = box.data(); + comboBox->setEditable(false); + comboBox->setInsertPolicy(QComboBox::NoInsert); + comboBox->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon); + comboBox->setDuplicatesEnabled(false); + comboBox->addItem(QIcon(":/material/icons/agender.svg"), toCatSexString(Competitor::Sex::UNDEFINED), Competitor::toSexString(Competitor::Sex::UNDEFINED)); + comboBox->addItem(QIcon(":/material/icons/male.svg"), toCatSexString(Competitor::Sex::MALE), Competitor::toSexString(Competitor::Sex::MALE)); + comboBox->addItem(QIcon(":/material/icons/female.svg"), toCatSexString(Competitor::Sex::FEMALE), Competitor::toSexString(Competitor::Sex::FEMALE)); + comboBox->addItem(QIcon(":/material/icons/transgender.svg"), toCatSexString(Competitor::Sex::MISC), Competitor::toSexString(Competitor::Sex::MISC)); +} + +QWidget *CategorySexDelegate::createEditor(QWidget *parent, QStyleOptionViewItem const &option, QModelIndex const &index) const +{ + Q_UNUSED(option) + Q_UNUSED(index) + + auto *comboBox = box.data(); + comboBox->setParent(parent); + + return comboBox; +} + +void CategorySexDelegate::destroyEditor(QWidget *editor, const QModelIndex &index) const +{ + Q_UNUSED(editor) + Q_UNUSED(index) +} + +void CategorySexDelegate::setEditorData(QWidget *editor, QModelIndex const &index) const +{ + // Get the value via index of the Model and put it into the ComboBox + auto *comboBox = static_cast(editor); + comboBox->setCurrentText(toCatSexString(Competitor::toSex(index.model()->data(index, Qt::EditRole).toString()))); +} + +void CategorySexDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, QModelIndex const &index) const +{ + auto const *comboBox = static_cast(editor); + model->setData(index, comboBox->currentData(Qt::UserRole), Qt::EditRole); +} + +void CategorySexDelegate::updateEditorGeometry(QWidget *editor, QStyleOptionViewItem const &option, QModelIndex const &index) const +{ + Q_UNUSED(index) + + editor->setGeometry(option.rect); +} + +QString CategorySexDelegate::toCatSexString(Competitor::Sex const sex) +{ + switch (sex) { + case Competitor::Sex::MALE: + return tr("Men"); + case Competitor::Sex::FEMALE: + return tr("Women"); + case Competitor::Sex::MISC: + return tr("Mixed"); + case Competitor::Sex::UNDEFINED: + return tr("All"); + default: + throw(ChronoRaceException(tr("Unexpected Sex enum value '%1'").arg(static_cast(sex)))); + } +} diff --git a/catsexdelegate.hpp b/catsexdelegate.hpp new file mode 100644 index 0000000..ad64e67 --- /dev/null +++ b/catsexdelegate.hpp @@ -0,0 +1,46 @@ +/***************************************************************************** + * Copyright (C) 2021 by Lorenzo Buzzi (lorenzo@buzzi.pro) * + * * + * 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 3 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ + +#ifndef CATSEXDELEGATE_HPP +#define CATSEXDELEGATE_HPP + +#include +#include +#include +#include + +#include "competitor.hpp" + +class CategorySexDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + explicit CategorySexDelegate(QObject *parent = Q_NULLPTR); + + QWidget *createEditor(QWidget *parent, QStyleOptionViewItem const &option, QModelIndex const &index) const override; + void destroyEditor(QWidget *editor, const QModelIndex &index) const override; + void setEditorData(QWidget *editor, QModelIndex const &index) const override; + void setModelData(QWidget *editor, QAbstractItemModel *model, QModelIndex const &index) const override; + void updateEditorGeometry(QWidget *editor, QStyleOptionViewItem const &option, QModelIndex const &index) const override; + +private: + QScopedPointer box { new QComboBox }; + + static QString toCatSexString(Competitor::Sex const sex); +}; + +#endif // CATSEXDELEGATE_HPP diff --git a/cattypedelegate.cpp b/cattypedelegate.cpp new file mode 100644 index 0000000..e843dd3 --- /dev/null +++ b/cattypedelegate.cpp @@ -0,0 +1,79 @@ +/***************************************************************************** + * Copyright (C) 2021 by Lorenzo Buzzi (lorenzo@buzzi.pro) * + * * + * 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 3 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ + +#include "cattypedelegate.hpp" +#include "lbcrexception.hpp" + +CategoryTypeDelegate::CategoryTypeDelegate(QObject *parent) : + QStyledItemDelegate(parent) +{ + auto *comboBox = box.data(); + comboBox->setEditable(false); + comboBox->setInsertPolicy(QComboBox::NoInsert); + comboBox->setDuplicatesEnabled(false); + comboBox->addItem(QIcon(":/material/icons/person.svg"), toCatTypeString(Category::Type::INDIVIDUAL), QVariant(Category::toTypeString(Category::Type::INDIVIDUAL))); + comboBox->addItem(QIcon(":/material/icons/group.svg"), toCatTypeString(Category::Type::CLUB), QVariant(Category::toTypeString(Category::Type::CLUB))); +} + +QWidget *CategoryTypeDelegate::createEditor(QWidget *parent, QStyleOptionViewItem const &option, QModelIndex const &index) const +{ + Q_UNUSED(option) + Q_UNUSED(index) + + auto *comboBox = box.data(); + comboBox->setParent(parent); + + return comboBox; +} + +void CategoryTypeDelegate::destroyEditor(QWidget *editor, const QModelIndex &index) const +{ + Q_UNUSED(editor) + Q_UNUSED(index) +} + +void CategoryTypeDelegate::setEditorData(QWidget *editor, QModelIndex const &index) const +{ + // Get the value via index of the Model and put it into the ComboBox + auto *comboBox = static_cast(editor); + comboBox->setCurrentText(toCatTypeString(Category::toType(index.model()->data(index, Qt::EditRole).toString()))); +} + +void CategoryTypeDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, QModelIndex const &index) const +{ + auto const *comboBox = static_cast(editor); + model->setData(index, comboBox->currentData(Qt::UserRole), Qt::EditRole); +} + +void CategoryTypeDelegate::updateEditorGeometry(QWidget *editor, QStyleOptionViewItem const &option, QModelIndex const &index) const +{ + Q_UNUSED(index) + + editor->setGeometry(option.rect); +} + +QString CategoryTypeDelegate::toCatTypeString(Category::Type type) +{ + switch (type) { + case Category::Type::INDIVIDUAL: + return tr("Individual"); + case Category::Type::CLUB: + return tr("Club"); + default: + throw(ChronoRaceException(tr("Unexpected Type enum value '%1'").arg(static_cast(type)))); + } +} diff --git a/cattypedelegate.hpp b/cattypedelegate.hpp new file mode 100644 index 0000000..bb4d8e5 --- /dev/null +++ b/cattypedelegate.hpp @@ -0,0 +1,46 @@ +/***************************************************************************** + * Copyright (C) 2021 by Lorenzo Buzzi (lorenzo@buzzi.pro) * + * * + * 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 3 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ + +#ifndef CATTYPEDELEGATE_HPP +#define CATTYPEDELEGATE_HPP + +#include +#include +#include +#include + +#include "category.hpp" + +class CategoryTypeDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + explicit CategoryTypeDelegate(QObject *parent = Q_NULLPTR); + + QWidget *createEditor(QWidget *parent, QStyleOptionViewItem const &option, QModelIndex const &index) const override; + void destroyEditor(QWidget *editor, const QModelIndex &index) const override; + void setEditorData(QWidget *editor, QModelIndex const &index) const override; + void setModelData(QWidget *editor, QAbstractItemModel *model, QModelIndex const &index) const override; + void updateEditorGeometry(QWidget *editor, QStyleOptionViewItem const &option, QModelIndex const &index) const override; + +private: + QScopedPointer box { new QComboBox }; + + static QString toCatTypeString(Category::Type type); +}; + +#endif // CATTYPEDELEGATE_HPP diff --git a/icons/agender.svg b/icons/agender.svg new file mode 100644 index 0000000..59bfc6b --- /dev/null +++ b/icons/agender.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/female.svg b/icons/female.svg new file mode 100644 index 0000000..d55d16e --- /dev/null +++ b/icons/female.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/group.svg b/icons/group.svg new file mode 100644 index 0000000..dbc2c93 --- /dev/null +++ b/icons/group.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/male.svg b/icons/male.svg new file mode 100644 index 0000000..1e70e32 --- /dev/null +++ b/icons/male.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/person.svg b/icons/person.svg new file mode 100644 index 0000000..a3f6b24 --- /dev/null +++ b/icons/person.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/transgender.svg b/icons/transgender.svg new file mode 100644 index 0000000..d1a1c6a --- /dev/null +++ b/icons/transgender.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/unknown_med.svg b/icons/unknown_med.svg new file mode 100644 index 0000000..b758426 --- /dev/null +++ b/icons/unknown_med.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/lbchronorace.cpp b/lbchronorace.cpp index ab0ed1c..7684447 100644 --- a/lbchronorace.cpp +++ b/lbchronorace.cpp @@ -40,7 +40,10 @@ LBChronoRace::LBChronoRace(QWidget *parent, QGuiApplication const *app) : teamsTable(parent), categoriesTable(parent), timingsTable(parent), - clubDelegate(&startListTable) + sexDelegate(&startListTable), + clubDelegate(&startListTable), + catSexDelegate(&categoriesTable), + catTypeDelegate(&categoriesTable) { startListFileName = lastSelectedPath.filePath(LBCHRONORACE_STARTLIST_DEFAULT); timingsFileName = lastSelectedPath.filePath(LBCHRONORACE_TIMINGS_DEFAULT); @@ -119,7 +122,10 @@ LBChronoRace::LBChronoRace(QWidget *parent, QGuiApplication const *app) : QObject::connect(ui->actionAboutQt, &QAction::triggered, this, &LBChronoRace::actionAboutQt); // tie the views with the related delegate instances + startListTable.setItemDelegateForColumn(static_cast(Competitor::Field::CMF_SEX), &sexDelegate); startListTable.setItemDelegateForColumn(static_cast(Competitor::Field::CMF_CLUB), &clubDelegate); + categoriesTable.setItemDelegateForColumn(static_cast(Category::Field::CTF_SEX), &catSexDelegate); + categoriesTable.setItemDelegateForColumn(static_cast(Category::Field::CTF_TEAM), &catTypeDelegate); } void LBChronoRace::setCounterTeams(int count) const diff --git a/lbchronorace.hpp b/lbchronorace.hpp index 741f20d..5c960b1 100644 --- a/lbchronorace.hpp +++ b/lbchronorace.hpp @@ -29,7 +29,10 @@ #include "chronoracetable.hpp" #include "chronoracedata.hpp" #include "chronoracetimings.hpp" +#include "sexdelegate.hpp" #include "clubdelegate.hpp" +#include "catsexdelegate.hpp" +#include "cattypedelegate.hpp" #ifndef LBCHRONORACE_NAME #error "LBCHRONORACE_NAME not set" @@ -89,7 +92,10 @@ public slots: ChronoRaceTimings timings; + SexDelegate sexDelegate; ClubDelegate clubDelegate; + CategorySexDelegate catSexDelegate; + CategoryTypeDelegate catTypeDelegate; bool loadRaceFile(QString const &fileName); diff --git a/materialicons.qrc b/materialicons.qrc index a24319a..fb9c9c7 100644 --- a/materialicons.qrc +++ b/materialicons.qrc @@ -25,5 +25,12 @@ icons/timer_play.svg icons/timer_play_big.svg icons/upload.svg + icons/female.svg + icons/agender.svg + icons/transgender.svg + icons/male.svg + icons/unknown_med.svg + icons/person.svg + icons/group.svg diff --git a/sexdelegate.cpp b/sexdelegate.cpp new file mode 100644 index 0000000..acdc5c6 --- /dev/null +++ b/sexdelegate.cpp @@ -0,0 +1,83 @@ +/***************************************************************************** + * Copyright (C) 2021 by Lorenzo Buzzi (lorenzo@buzzi.pro) * + * * + * 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 3 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ + +#include "sexdelegate.hpp" +#include "lbcrexception.hpp" + +SexDelegate::SexDelegate(QObject *parent) : + QStyledItemDelegate(parent) +{ + auto *comboBox = box.data(); + comboBox->setEditable(false); + comboBox->setInsertPolicy(QComboBox::NoInsert); + comboBox->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon); + comboBox->setDuplicatesEnabled(false); + comboBox->addItem(QIcon(":/material/icons/unknown_med.svg"), toSexString(Competitor::Sex::UNDEFINED), Competitor::toSexString(Competitor::Sex::UNDEFINED)); + comboBox->addItem(QIcon(":/material/icons/male.svg"), toSexString(Competitor::Sex::MALE), Competitor::toSexString(Competitor::Sex::MALE)); + comboBox->addItem(QIcon(":/material/icons/female.svg"), toSexString(Competitor::Sex::FEMALE), Competitor::toSexString(Competitor::Sex::FEMALE)); +} + +QWidget *SexDelegate::createEditor(QWidget *parent, QStyleOptionViewItem const &option, QModelIndex const &index) const +{ + Q_UNUSED(option) + Q_UNUSED(index) + + auto *comboBox = box.data(); + comboBox->setParent(parent); + + return comboBox; +} + +void SexDelegate::destroyEditor(QWidget *editor, const QModelIndex &index) const +{ + Q_UNUSED(editor) + Q_UNUSED(index) +} + +void SexDelegate::setEditorData(QWidget *editor, QModelIndex const &index) const +{ + // Get the value via index of the Model and put it into the ComboBox + auto *comboBox = static_cast(editor); + comboBox->setCurrentText(toSexString(Competitor::toSex(index.model()->data(index, Qt::EditRole).toString()))); +} + +void SexDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, QModelIndex const &index) const +{ + auto const *comboBox = static_cast(editor); + model->setData(index, comboBox->currentData(Qt::UserRole), Qt::EditRole); +} + +void SexDelegate::updateEditorGeometry(QWidget *editor, QStyleOptionViewItem const &option, QModelIndex const &index) const +{ + Q_UNUSED(index) + + editor->setGeometry(option.rect); +} + +QString SexDelegate::toSexString(Competitor::Sex const sex) +{ + switch (sex) { + case Competitor::Sex::MALE: + return tr("Male"); + case Competitor::Sex::FEMALE: + return tr("Female"); + case Competitor::Sex::UNDEFINED: + return tr("Not set"); + default: + throw(ChronoRaceException(tr("Unexpected Sex enum value '%1'").arg(static_cast(sex)))); + } +} diff --git a/sexdelegate.hpp b/sexdelegate.hpp new file mode 100644 index 0000000..94c2439 --- /dev/null +++ b/sexdelegate.hpp @@ -0,0 +1,46 @@ +/***************************************************************************** + * Copyright (C) 2021 by Lorenzo Buzzi (lorenzo@buzzi.pro) * + * * + * 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 3 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ + +#ifndef SEXDELEGATE_HPP +#define SEXDELEGATE_HPP + +#include +#include +#include +#include + +#include "competitor.hpp" + +class SexDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + explicit SexDelegate(QObject *parent = Q_NULLPTR); + + QWidget *createEditor(QWidget *parent, QStyleOptionViewItem const &option, QModelIndex const &index) const override; + void destroyEditor(QWidget *editor, const QModelIndex &index) const override; + void setEditorData(QWidget *editor, QModelIndex const &index) const override; + void setModelData(QWidget *editor, QAbstractItemModel *model, QModelIndex const &index) const override; + void updateEditorGeometry(QWidget *editor, QStyleOptionViewItem const &option, QModelIndex const &index) const override; + +private: + QScopedPointer box { new QComboBox }; + + static QString toSexString(Competitor::Sex const sex); +}; + +#endif // SEXDELEGATE_HPP diff --git a/startlistmodel.cpp b/startlistmodel.cpp index 8f4258d..9e9c2e8 100644 --- a/startlistmodel.cpp +++ b/startlistmodel.cpp @@ -192,7 +192,7 @@ bool StartListModel::setData(QModelIndex const &index, QVariant const &value, in case static_cast(Competitor::Field::CMF_SEX): try { Competitor::Sex sex = Competitor::toSex(value.toString().trimmed(), true); - retval = (sex != Competitor::Sex::UNDEFINED); + retval = (sex != Competitor::Sex::MISC); if (retval) startList[index.row()].setSex(sex); } catch (ChronoRaceException &ex) { emit error(ex.getMessage()); diff --git a/translations/LBChronoRace_en.ts b/translations/LBChronoRace_en.ts index 575983f..90fa913 100644 --- a/translations/LBChronoRace_en.ts +++ b/translations/LBChronoRace_en.ts @@ -77,10 +77,6 @@ Individual (I) or Team (T) Individual (I) or Team (T) - - Male (M), Female (F), Misc (X) or Unspecified (U) - Male (M), Female (F), Misc (X) or Unspecified (U) - The category will include competitors born up to and including this year (i.e. 2000); 0 to disable The category will include competitors born up to and including this year (i.e. 2000); 0 to disable @@ -121,6 +117,10 @@ Category Short Name Category Short Name + + Men (M), Women (F), Mixed (X) or All (U) + Men (M), Women (F), Mixed (X) or All (U) + Category @@ -128,6 +128,52 @@ Illegal category type - expected 'I' or 'T' - found %1 Illegal category type - expected 'I' or 'T' - found %1 + + Unexpected Type enum value '%1' + Unexpected Type enum value '%1' + + + Illegal type '%1' + Illegal type '%1' + + + + CategorySexDelegate + + Men + Men + + + Women + Women + + + Mixed + Mixed + + + All + All + + + Unexpected Sex enum value '%1' + Unexpected Sex enum value '%1' + + + + CategoryTypeDelegate + + Individual + Individual + + + Club + Club + + + Unexpected Type enum value '%1' + Unexpected Type enum value '%1' + ChronoRaceData @@ -608,10 +654,6 @@ Continue? View Clubs List View Clubs List - - Teams - Teams - Competitors Competitors @@ -1285,6 +1327,25 @@ Please uodate the application. You can exclude some categories from the generated rankings. + + SexDelegate + + Male + Male + + + Female + Female + + + Unexpected Sex enum value '%1' + Unexpected Sex enum value '%1' + + + Not set + Not set + + StartListModel diff --git a/translations/LBChronoRace_it.ts b/translations/LBChronoRace_it.ts index 18ab1c4..86c83be 100644 --- a/translations/LBChronoRace_it.ts +++ b/translations/LBChronoRace_it.ts @@ -77,10 +77,6 @@ Individual (I) or Team (T) Individuale (I) o Società (T) - - Male (M), Female (F), Misc (X) or Unspecified (U) - Maschile (M), Femminile (F), Mista (X) o Non specificato (U) - The category will include competitors born up to and including this year (i.e. 2000); 0 to disable La categoria include concorrenti nati fino a quest'anno incluso (es. 2000); 0 per disabilitare @@ -121,6 +117,10 @@ Category Short Name Abbreviazione Categoria + + Men (M), Women (F), Mixed (X) or All (U) + Maschile (M), Femminile (F), Mista (X) o Tutti (U) + Category @@ -128,6 +128,52 @@ Illegal category type - expected 'I' or 'T' - found %1 Categoria errata - valori ammessi 'I' o 'T' - trovato %1 + + Unexpected Type enum value '%1' + Valore enumerazione Type '%1' non valido + + + Illegal type '%1' + Tipo non valido '%1' + + + + CategorySexDelegate + + Men + Maschile + + + Women + Femminile + + + Mixed + Mista + + + All + Tutti + + + Unexpected Sex enum value '%1' + Valore enumerazione Sex '%1' non valido + + + + CategoryTypeDelegate + + Individual + Individuale + + + Club + Società + + + Unexpected Type enum value '%1' + Valore enumerazione Type '%1' non valido + ChronoRaceData @@ -608,10 +654,6 @@ Continuare? View Clubs List Visualizza Lista Società - - Teams - Squadre - Competitors Concorrenti @@ -1285,6 +1327,25 @@ Aggiornare l'applicazione. Puoi escludere alcune categorie dalle classifiche generate. + + SexDelegate + + Male + Maschio + + + Female + Femmina + + + Unexpected Sex enum value '%1' + Valore enumerazione Sex '%1' non valido + + + Not set + Non impostato + + StartListModel From 9c540ee24470a329629abda0db31c5a15fbdcc36 Mon Sep 17 00:00:00 2001 From: Lorenzo Buzzi Date: Tue, 2 Jul 2024 15:31:40 +0200 Subject: [PATCH 5/5] Adaptive columns width --- catsexdelegate.cpp | 6 ++++++ catsexdelegate.hpp | 1 + cattypedelegate.cpp | 6 ++++++ cattypedelegate.hpp | 1 + chronoracetable.cpp | 1 + clubdelegate.cpp | 6 ++++++ clubdelegate.hpp | 1 + sexdelegate.cpp | 6 ++++++ sexdelegate.hpp | 1 + 9 files changed, 29 insertions(+) diff --git a/catsexdelegate.cpp b/catsexdelegate.cpp index e481a72..1e92d0d 100644 --- a/catsexdelegate.cpp +++ b/catsexdelegate.cpp @@ -26,6 +26,7 @@ CategorySexDelegate::CategorySexDelegate(QObject *parent) : comboBox->setInsertPolicy(QComboBox::NoInsert); comboBox->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon); comboBox->setDuplicatesEnabled(false); + comboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents); comboBox->addItem(QIcon(":/material/icons/agender.svg"), toCatSexString(Competitor::Sex::UNDEFINED), Competitor::toSexString(Competitor::Sex::UNDEFINED)); comboBox->addItem(QIcon(":/material/icons/male.svg"), toCatSexString(Competitor::Sex::MALE), Competitor::toSexString(Competitor::Sex::MALE)); comboBox->addItem(QIcon(":/material/icons/female.svg"), toCatSexString(Competitor::Sex::FEMALE), Competitor::toSexString(Competitor::Sex::FEMALE)); @@ -62,6 +63,11 @@ void CategorySexDelegate::setModelData(QWidget *editor, QAbstractItemModel *mode model->setData(index, comboBox->currentData(Qt::UserRole), Qt::EditRole); } +QSize CategorySexDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + return this->box.data()->sizeHint(); +} + void CategorySexDelegate::updateEditorGeometry(QWidget *editor, QStyleOptionViewItem const &option, QModelIndex const &index) const { Q_UNUSED(index) diff --git a/catsexdelegate.hpp b/catsexdelegate.hpp index ad64e67..1c40c45 100644 --- a/catsexdelegate.hpp +++ b/catsexdelegate.hpp @@ -35,6 +35,7 @@ class CategorySexDelegate : public QStyledItemDelegate void destroyEditor(QWidget *editor, const QModelIndex &index) const override; void setEditorData(QWidget *editor, QModelIndex const &index) const override; void setModelData(QWidget *editor, QAbstractItemModel *model, QModelIndex const &index) const override; + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; void updateEditorGeometry(QWidget *editor, QStyleOptionViewItem const &option, QModelIndex const &index) const override; private: diff --git a/cattypedelegate.cpp b/cattypedelegate.cpp index e843dd3..7d69a28 100644 --- a/cattypedelegate.cpp +++ b/cattypedelegate.cpp @@ -25,6 +25,7 @@ CategoryTypeDelegate::CategoryTypeDelegate(QObject *parent) : comboBox->setEditable(false); comboBox->setInsertPolicy(QComboBox::NoInsert); comboBox->setDuplicatesEnabled(false); + comboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents); comboBox->addItem(QIcon(":/material/icons/person.svg"), toCatTypeString(Category::Type::INDIVIDUAL), QVariant(Category::toTypeString(Category::Type::INDIVIDUAL))); comboBox->addItem(QIcon(":/material/icons/group.svg"), toCatTypeString(Category::Type::CLUB), QVariant(Category::toTypeString(Category::Type::CLUB))); } @@ -59,6 +60,11 @@ void CategoryTypeDelegate::setModelData(QWidget *editor, QAbstractItemModel *mod model->setData(index, comboBox->currentData(Qt::UserRole), Qt::EditRole); } +QSize CategoryTypeDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + return this->box.data()->sizeHint(); +} + void CategoryTypeDelegate::updateEditorGeometry(QWidget *editor, QStyleOptionViewItem const &option, QModelIndex const &index) const { Q_UNUSED(index) diff --git a/cattypedelegate.hpp b/cattypedelegate.hpp index bb4d8e5..31522ce 100644 --- a/cattypedelegate.hpp +++ b/cattypedelegate.hpp @@ -35,6 +35,7 @@ class CategoryTypeDelegate : public QStyledItemDelegate void destroyEditor(QWidget *editor, const QModelIndex &index) const override; void setEditorData(QWidget *editor, QModelIndex const &index) const override; void setModelData(QWidget *editor, QAbstractItemModel *model, QModelIndex const &index) const override; + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; void updateEditorGeometry(QWidget *editor, QStyleOptionViewItem const &option, QModelIndex const &index) const override; private: diff --git a/chronoracetable.cpp b/chronoracetable.cpp index 2baa859..a4470de 100644 --- a/chronoracetable.cpp +++ b/chronoracetable.cpp @@ -24,6 +24,7 @@ ChronoRaceTable::ChronoRaceTable(QWidget *parent) : QDialog(parent) ui->setupUi(this); ui->tableView->setSortingEnabled(true); + ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::ResizeToContents); QObject::connect(ui->tableView->horizontalHeader(), &QHeaderView::sortIndicatorChanged, ui->tableView, &QTableView::sortByColumn); QObject::connect(ui->rowAdd, &QPushButton::clicked, this, &ChronoRaceTable::rowAdd); diff --git a/clubdelegate.cpp b/clubdelegate.cpp index 34ad582..2a92618 100644 --- a/clubdelegate.cpp +++ b/clubdelegate.cpp @@ -25,6 +25,7 @@ ClubDelegate::ClubDelegate(QObject *parent) : comboBox->setEditable(true); comboBox->setInsertPolicy(QComboBox::InsertAlphabetically); comboBox->setDuplicatesEnabled(false); + comboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents); comboBox->addItems(CRLoader::getClubs()); } @@ -58,6 +59,11 @@ void ClubDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, QMod model->setData(index, comboBox->currentData(Qt::EditRole), Qt::EditRole); } +QSize ClubDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + return this->box.data()->sizeHint(); +} + void ClubDelegate::updateEditorGeometry(QWidget *editor, QStyleOptionViewItem const &option, QModelIndex const &index) const { Q_UNUSED(index) diff --git a/clubdelegate.hpp b/clubdelegate.hpp index 90abfde..cf55f7c 100644 --- a/clubdelegate.hpp +++ b/clubdelegate.hpp @@ -33,6 +33,7 @@ class ClubDelegate : public QStyledItemDelegate void destroyEditor(QWidget *editor, const QModelIndex &index) const override; void setEditorData(QWidget *editor, QModelIndex const &index) const override; void setModelData(QWidget *editor, QAbstractItemModel *model, QModelIndex const &index) const override; + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; void updateEditorGeometry(QWidget *editor, QStyleOptionViewItem const &option, QModelIndex const &index) const override; private: diff --git a/sexdelegate.cpp b/sexdelegate.cpp index acdc5c6..bf5388f 100644 --- a/sexdelegate.cpp +++ b/sexdelegate.cpp @@ -26,6 +26,7 @@ SexDelegate::SexDelegate(QObject *parent) : comboBox->setInsertPolicy(QComboBox::NoInsert); comboBox->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon); comboBox->setDuplicatesEnabled(false); + comboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents); comboBox->addItem(QIcon(":/material/icons/unknown_med.svg"), toSexString(Competitor::Sex::UNDEFINED), Competitor::toSexString(Competitor::Sex::UNDEFINED)); comboBox->addItem(QIcon(":/material/icons/male.svg"), toSexString(Competitor::Sex::MALE), Competitor::toSexString(Competitor::Sex::MALE)); comboBox->addItem(QIcon(":/material/icons/female.svg"), toSexString(Competitor::Sex::FEMALE), Competitor::toSexString(Competitor::Sex::FEMALE)); @@ -61,6 +62,11 @@ void SexDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, QMode model->setData(index, comboBox->currentData(Qt::UserRole), Qt::EditRole); } +QSize SexDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + return this->box.data()->sizeHint(); +} + void SexDelegate::updateEditorGeometry(QWidget *editor, QStyleOptionViewItem const &option, QModelIndex const &index) const { Q_UNUSED(index) diff --git a/sexdelegate.hpp b/sexdelegate.hpp index 94c2439..26e0aec 100644 --- a/sexdelegate.hpp +++ b/sexdelegate.hpp @@ -35,6 +35,7 @@ class SexDelegate : public QStyledItemDelegate void destroyEditor(QWidget *editor, const QModelIndex &index) const override; void setEditorData(QWidget *editor, QModelIndex const &index) const override; void setModelData(QWidget *editor, QAbstractItemModel *model, QModelIndex const &index) const override; + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; void updateEditorGeometry(QWidget *editor, QStyleOptionViewItem const &option, QModelIndex const &index) const override; private: