diff options
| author | Steru <jerrydream111@gmail.com> | 2024-08-16 22:19:42 +0200 | 
|---|---|---|
| committer | Steru <jerrydream111@gmail.com> | 2024-08-16 23:58:46 +0200 | 
| commit | 88b1b119dfa35f36b64d81dbe6c84f46d86455c5 (patch) | |
| tree | 864ba9c747ef86d61b6aeb01e8985676f906bd3e | |
| parent | f24b4dcbd11336dabfd146c656e2437e4393b225 (diff) | |
Compacted competitors into one object, deleted API class (now in sportmodel).
| -rw-r--r-- | CMakeLists.txt | 2 | ||||
| -rw-r--r-- | res/gui/EventInfoPage.qml | 6 | ||||
| -rw-r--r-- | res/gui/EventsPage.qml | 2 | ||||
| -rw-r--r-- | src/api/OlympicsAPI.cpp | 140 | ||||
| -rw-r--r-- | src/api/OlympicsAPI.h | 72 | ||||
| -rw-r--r-- | src/model/Competitor.cpp | 114 | ||||
| -rw-r--r-- | src/model/Competitor.h | 71 | ||||
| -rw-r--r-- | src/model/CompetitorWithResults.cpp | 61 | ||||
| -rw-r--r-- | src/model/CompetitorWithResults.h | 40 | ||||
| -rw-r--r-- | src/model/EventInfo.cpp | 9 | ||||
| -rw-r--r-- | src/model/EventInfo.h | 23 | ||||
| -rw-r--r-- | src/model/MedalWinner.cpp | 57 | ||||
| -rw-r--r-- | src/model/MedalWinner.h | 39 | ||||
| -rw-r--r-- | src/model/SportModel.cpp | 161 | ||||
| -rw-r--r-- | src/model/SportModel.h | 25 | 
15 files changed, 243 insertions, 579 deletions
| diff --git a/CMakeLists.txt b/CMakeLists.txt index af81cc4..96b3d35 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,8 +23,6 @@ qt_add_qml_module(itat_challenge_olympics      SOURCES          src/model/Competitor.cpp          src/model/Competitor.h -        src/model/CompetitorWithResults.cpp -        src/model/CompetitorWithResults.h          src/model/EventInfo.cpp          src/model/EventInfo.h          src/model/FilterModel.cpp diff --git a/res/gui/EventInfoPage.qml b/res/gui/EventInfoPage.qml index d04716b..6c46a7f 100644 --- a/res/gui/EventInfoPage.qml +++ b/res/gui/EventInfoPage.qml @@ -5,7 +5,7 @@ import QtQuick.Controls  Page {    id: root    property string eventName -  property list<string> competitors +  property list<QtObject> competitors    header: ToolBar {      ToolButton { @@ -31,9 +31,9 @@ Page {      bottomMargin: 48      rightMargin: 48      spacing: 20 -    model: competitors +    model: eventName      delegate: ItemDelegate { -      text: modelData +      text: "sadly not working..."        width: listView.width - listView.leftMargin - listView.rightMargin        height: avatar.implicitHeight + 32        leftPadding: avatar.implicitWidth + 32 diff --git a/res/gui/EventsPage.qml b/res/gui/EventsPage.qml index 0ce21e4..d21b5bb 100644 --- a/res/gui/EventsPage.qml +++ b/res/gui/EventsPage.qml @@ -254,7 +254,7 @@ Page {        model: filter        delegate: ItemDelegate {          required property string eventName -        required property list<string> competitors +        property list<QtObject> competitors          text: eventName          width: listView.width - listView.leftMargin - listView.rightMargin          height: avatar.height  diff --git a/src/api/OlympicsAPI.cpp b/src/api/OlympicsAPI.cpp deleted file mode 100644 index 0334800..0000000 --- a/src/api/OlympicsAPI.cpp +++ /dev/null @@ -1,140 +0,0 @@ - -#include "OlympicsAPI.h" -#include <string> -#include <stdexcept> - -// networking -#include <QEventLoop> -#include <QNetworkAccessManager> -#include <QNetworkRequest> -#include <QNetworkReply> -#include <QUrl> -#include <QUrlQuery> - -// json parsing -#include <QFile> -#include <QJsonValue> -#include <QJsonDocument> -#include <QJsonObject> -#include <QVariantMap> -#include <QJsonArray> - - -using namespace std; - -/** - * @brief OlympicsAPI::getSportData Requests the current data from the Olympics API of a certain discipline. - * @param sport The discipline to request. - * @return The current information provided by the API endpoint. - */ -QJsonObject OlympicsAPI::getSportData(OlympicsAPI::Disciplines sport) { -    string shortName = this->getDisciplineShort(sport); - -    if (USE_API_REQUEST) { -        // create custom temporary event loop on stack -        QEventLoop eventLoop; - -        // "quit()" the event-loop, when the network request "finished()" -        QNetworkAccessManager mgr; -        QObject::connect(&mgr, SIGNAL(finished(QNetworkReply*)), &eventLoop, SLOT(quit())); - -        QString endpoint = (API_LINK + shortName).c_str(); - -        // the HTTP request -        QNetworkRequest req( (QUrl( endpoint )) ); -        QNetworkReply *reply = mgr.get(req); -        eventLoop.exec(); // blocks stack until "finished()" has been called - -        if (reply->error() == QNetworkReply::NoError) { -            //success - -            QString strReply = (QString)reply->readAll(); - -            //parse json -            QJsonDocument jsonResponse = QJsonDocument::fromJson(strReply.toUtf8()); - -            QJsonObject jsonObj = jsonResponse.object(); - -            delete reply; - -            return jsonObj; -        } -        else { -            //failure -            delete reply; - -            throw invalid_argument("API request failed."); -        } -    } - -    // if API is not used, open locally stored data -    QString filePath = ("../../res/mock/" + shortName + ".json").c_str(); -    QFile file( filePath ); - -    if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { -        throw invalid_argument("Could not open file to read data of the given discipline."); -    } else { -        QString text = file.readAll(); -        file.close(); -        return (QJsonDocument::fromJson(text.toUtf8())).object(); -    } -} - -/** - * @brief OlympicsAPI::getDisciplineShort Get the discipline's short name defined by the IOC (International Olympic Committee) - * @param sport The sport you want to get the name from. - * @return The short name as a string. - */ -string OlympicsAPI::getDisciplineShort(OlympicsAPI::Disciplines sport) { -    switch (sport) { -    case OlympicsAPI::Disciplines::AquaticsArtisticSwimming: return "SWA"; -    case OlympicsAPI::Disciplines::AquaticsDiving: return "DIV"; -    case OlympicsAPI::Disciplines::AquaticsMarathonSwimming: return "OWS"; -    case OlympicsAPI::Disciplines::AquaticsSwimming: return "SWM"; -    case OlympicsAPI::Disciplines::AquaticsWaterPolo: return "WPO"; -    case OlympicsAPI::Disciplines::Archery: return "ARC"; -    case OlympicsAPI::Disciplines::Athletics: return "ATH"; -    case OlympicsAPI::Disciplines::Badminton: return "BDM"; -    case OlympicsAPI::Disciplines::Basketball3v3: return "BK3"; -    case OlympicsAPI::Disciplines::Basketball: return "BKB"; -    case OlympicsAPI::Disciplines::Boxing: return "BOX"; -    case OlympicsAPI::Disciplines::Breaking: return "BKG"; -    case OlympicsAPI::Disciplines::CanoeingSprint: return "CSP"; -    case OlympicsAPI::Disciplines::CanoeingSlalom: return "CSL"; -    case OlympicsAPI::Disciplines::CyclingBMXFreestyle: return "BMF"; -    case OlympicsAPI::Disciplines::CyclingBMXRacing: return "BMX"; -    case OlympicsAPI::Disciplines::CyclingMaountainBike: return "MTB"; -    case OlympicsAPI::Disciplines::CyclingRoad: return "CRD"; -    case OlympicsAPI::Disciplines::CyclingTrack: return "CTR"; -    case OlympicsAPI::Disciplines::EquestrianDressage: return "EDR"; -    case OlympicsAPI::Disciplines::EquestrianEventing: return "EVE"; -    case OlympicsAPI::Disciplines::EquestrianJumping: return "EJP"; -    case OlympicsAPI::Disciplines::Fencing: return "FEN"; -    case OlympicsAPI::Disciplines::FieldHockey: return "HOC"; -    case OlympicsAPI::Disciplines::Football: return "FBL"; -    case OlympicsAPI::Disciplines::Golf: return "GLF"; -    case OlympicsAPI::Disciplines::GymnasticsArtistic: return "GAR"; -    case OlympicsAPI::Disciplines::GymnasticsRhythmic: return "GRY"; -    case OlympicsAPI::Disciplines::GymnasticsTrampoline: return "GTR"; -    case OlympicsAPI::Disciplines::HandballIndoor: return "HBL"; -    case OlympicsAPI::Disciplines::Judo: return "JUD"; -    case OlympicsAPI::Disciplines::ModernPentathlon: return "MPN"; -    case OlympicsAPI::Disciplines::Rowing: return "ROW"; -    case OlympicsAPI::Disciplines::Rugby7: return "RU7"; -    case OlympicsAPI::Disciplines::Sailing: return "SAL"; -    case OlympicsAPI::Disciplines::Shooting: return "SHO"; -    case OlympicsAPI::Disciplines::Skateboarding: return "SKB"; -    case OlympicsAPI::Disciplines::SportClimbing: return "CLB"; -    case OlympicsAPI::Disciplines::Surfing: return "SRF"; -    case OlympicsAPI::Disciplines::TableTennis: return "TTE"; -    case OlympicsAPI::Disciplines::Taekwondo: return "TKW"; -    case OlympicsAPI::Disciplines::Tennis: return "TEN"; -    case OlympicsAPI::Disciplines::Triathlon: return "TRI"; -    case OlympicsAPI::Disciplines::VolleyballBeach: return "VBV"; -    case OlympicsAPI::Disciplines::VolleyballIndoor: return "VVO"; -    case OlympicsAPI::Disciplines::Weightlifting: return "WLF"; -    case OlympicsAPI::Disciplines::WrestlingFreestyle: return "WRE"; -    case OlympicsAPI::Disciplines::WrestlingGrecoRoman: return "WRG"; -    default: return "ARC"; // default, which should not be possible, because of enum -    } -} diff --git a/src/api/OlympicsAPI.h b/src/api/OlympicsAPI.h deleted file mode 100644 index a301cf8..0000000 --- a/src/api/OlympicsAPI.h +++ /dev/null @@ -1,72 +0,0 @@ - -#pragma once - -#define API_LINK "https://sph-s-api.olympics.com/summer/schedules/api/ENG/schedule/discipline/" - -#include <string> -#include <QJsonObject> - -// TODO: change this to true to use the olympics api, instead of the mock date in res/mock/ -#define USE_API_REQUEST false - -using namespace std; - -class OlympicsAPI { - -public: - -    enum Disciplines { -        AquaticsArtisticSwimming, -        AquaticsDiving, -        AquaticsMarathonSwimming, -        AquaticsSwimming, -        AquaticsWaterPolo, -        Archery, -        Athletics, -        Badminton, -        Basketball3v3, -        Basketball, -        Boxing, -        Breaking, -        CanoeingSprint, -        CanoeingSlalom, -        CyclingBMXFreestyle, -        CyclingBMXRacing, -        CyclingMaountainBike, -        CyclingRoad, -        CyclingTrack, -        EquestrianDressage, -        EquestrianEventing, -        EquestrianJumping, -        Fencing, -        FieldHockey, -        Football, -        Golf, -        GymnasticsArtistic, -        GymnasticsRhythmic, -        GymnasticsTrampoline, -        HandballIndoor, -        Judo, -        ModernPentathlon, -        Rowing, -        Rugby7, -        Sailing, -        Shooting, -        Skateboarding, -        SportClimbing, -        Surfing, -        TableTennis, -        Taekwondo, -        Tennis, -        Triathlon, -        VolleyballBeach, -        VolleyballIndoor, -        Weightlifting, -        WrestlingFreestyle, -        WrestlingGrecoRoman -    }; - -    QJsonObject getSportData(Disciplines sport); -    string getDisciplineShort(Disciplines sport); - -}; diff --git a/src/model/Competitor.cpp b/src/model/Competitor.cpp index a584689..c0ee01d 100644 --- a/src/model/Competitor.cpp +++ b/src/model/Competitor.cpp @@ -1,22 +1,126 @@  #include "Competitor.h" +/** + * Reads certain properties from a competitor json object. + * These are: code, name, noc, results + * + * For further information on 'results' see [Competitor::setResult]. + * + * Does not set the amounts of medals. For this, call [Competitor::setMedals]. + * + * @param competitor The competitor as a QJsonObject. + * @return True if successful. + */  bool Competitor::setCompetitor(const QJsonObject &competitor) {      if (!competitor.contains("code")          || !competitor.contains("name") -        || !competitor.contains("m_noc")) { -        throw invalid_argument("Not a competitor object."); +        || !competitor.contains("noc")) { +        return false;      }      setCode(competitor["code"].toInt());      setName(competitor["name"].toString()); -    setNOC(competitor["m_noc"].toString()); -    return true; +    setNOC(competitor["noc"].toString()); + +    if (!competitor.contains("results")) return false; +    QJsonObject results = competitor["results"].toObject(); +    return setResults(results);  } -bool Competitor::setCompetitor(const Competitor &competitor) { +/** + * Copies all values of a given competitor. + * + * @param competitor The competitor to copy. + */ +void Competitor::setCompetitor(const Competitor &competitor) {      setCode(competitor.m_code);      setName(competitor.m_name);      setNOC(competitor.m_noc); +    setMark(competitor.m_mark); +    setMedalType(competitor.m_medalType); +    setStatistic(competitor.m_statistic); +    setGold(competitor.m_gold); +    setSilver(competitor.m_silver); +    setBronze(competitor.m_bronze); +} + +/** + * Replaces/sets the results of a competitor. + * + * @param results The results of the competitor. + * @return True, if successful. + */ +bool Competitor::setResults(const QJsonObject &results) { +    if (!results.contains("mark") +        || !results.contains("medalType")) { +        return false; +    } + +    setMark(results["mark"].toString()); +    setMedalType(results["medalType"].toString()); + +    return true; +} + +/** + * Replaces/sets the won medals of a competitor. + * + * @param medals The won medals with their amount. + * @return True, if successful. + */ +bool Competitor::setMedals(const map<QString, int> &medals) { +    if (medals.find("ME_GOLD") == medals.end() +        || medals.find("ME_SILVER") == medals.end() +        || medals.find("ME_BRONZE") == medals.end()) return false; + +    setGold(medals.find("ME_GOLD")->second); +    setSilver(medals.find("ME_SILVER")->second); +    setBronze(medals.find("ME_BRONZE")->second); +      return true;  } + +/** + * Static compare method, which can compare the result times or points of two competitors. + * Returns true, if the left competitor (lComp) got a real lesser score than the right competitor (rComp). + * + * @param lComp First competitor to compare. + * @param rComp Second competitor to compare. + * @return True, if the second competitor got a higher score. + */ +bool Competitor::compareMark(Competitor lComp, Competitor rComp) { +    QString l = lComp.mark(); +    QString r = rComp.mark(); + +    // check if values are numerical (-> not time values) +    if (!l.contains(":") || !r.contains(":")) { +        return l.toFloat() < r.toFloat(); +    } + +    // compare time values if not numerical +    QString lTime(""), rTime(""); + +    for (QChar c : l) if (c.isDigit()) lTime.append(c); +    for (QChar c : r) if (c.isDigit()) rTime.append(c); + +    return lTime.compare(rTime) < 0; +} + +/** + * Static compare method, which can compare the amount of medals of two competitors. + * Gold has the highest priority, then m_silver and finally m_bronze. + * + * @param lComp First competitor to compare. + * @param rComp Second competitor to compare. + * @return True, if the second competitor got more or higher medals. + */ +bool Competitor::compareMedals(Competitor lComp, Competitor rComp) { +    // create difference between medal amounts +    int gold = lComp.gold() - rComp.gold(); +    int silver = lComp.silver() - rComp.silver(); +    int bronze = lComp.bronze() - rComp.bronze(); + +    // compare medal differences +    return gold < 0 || (gold == 0 && (silver < 0 || (silver == 0 && bronze < 0))); +} diff --git a/src/model/Competitor.h b/src/model/Competitor.h index 1913325..e27b537 100644 --- a/src/model/Competitor.h +++ b/src/model/Competitor.h @@ -14,39 +14,82 @@ class Competitor : public QObject {      Q_OBJECT -    Q_PROPERTY(int code READ code NOTIFY nCode) -    Q_PROPERTY(QString name READ name NOTIFY nName) -    Q_PROPERTY(QString noc READ noc NOTIFY nNoc) +    Q_PROPERTY(int code READ code NOTIFY codeChanged) +    Q_PROPERTY(QString name READ name NOTIFY nameChanged) +    Q_PROPERTY(QString noc READ noc NOTIFY nocChanged) + +    // results in a certain event/category +    Q_PROPERTY(QString mark READ mark NOTIFY markChanged) +    Q_PROPERTY(QString medalType READ medalType NOTIFY medalTypeChanged) +    Q_PROPERTY(QString statistic READ statistic NOTIFY statisticChanged) + +    // medal amounts in the whole discipline +    Q_PROPERTY(int gold READ gold NOTIFY goldChanged) +    Q_PROPERTY(int silver READ silver NOTIFY silverChanged) +    Q_PROPERTY(int bronze READ bronze NOTIFY bronzeChanged)  public:      explicit Competitor(QObject *parent) : QObject(parent) {} -    int getCode() { return this->m_code; } -    QString getName() { return this->m_name; } -    QString getNOC() { return this->m_noc; } +    // getter +    int code() const { return this->m_code; } +    QString name() const { return this->m_name; } +    QString noc() const { return this->m_noc; } +    QString mark() const { return this->m_mark; } +    QString medalType() const { return this->m_medalType; } +    QString statistic() const { return this->m_statistic; } +    int gold() const { return this->m_gold; } +    int silver() const { return this->m_silver; } +    int bronze() const { return this->m_bronze; } +    // setter      void setCode(int code) { this->m_code = code; }      void setName(QString name) { this->m_name = name; }      void setNOC(QString noc) { this->m_noc = noc; } +    void setMark(QString mark) { this->m_mark = mark; } +    void setMedalType(QString medalType) { this->m_medalType = medalType; } +    void setStatistic(QString stat) { this->m_statistic = stat; } +    void setGold(int gold) { this->m_gold = gold; } +    void setSilver(int silver) { this->m_silver = silver; } +    void setBronze(int bronze) { this->m_bronze = bronze; } + +    bool setResults(const QJsonObject &results); +    bool setMedals(const map<QString, int> &medals);      bool setCompetitor(const QJsonObject &competitor); -    bool setCompetitor(const Competitor &competitor); +    void setCompetitor(const Competitor &competitor); -    static bool compareName(const Competitor &left, const Competitor &right) { -        return left.m_name.compare(right.m_name) < 0; +    static bool compareName(Competitor lComp, Competitor rComp) { +        return lComp.m_name.compare(rComp.m_name) < 0;      } -    static bool compareNOC(const Competitor &left, const Competitor &right) { -        return left.m_noc.compare(right.m_noc) < 0; +    static bool compareNOC(Competitor lComp, Competitor rComp) { +        return lComp.m_noc.compare(rComp.m_noc) < 0;      } +    static bool compareMark(Competitor lComp, Competitor rComp); +    static bool compareMedals(Competitor lComp, Competitor rComp); +  signals: -    void nCode(); -    void nName(); -    void nNoc(); +    void codeChanged(); +    void nameChanged(); +    void nocChanged(); +    void markChanged(); +    void medalTypeChanged(); +    void statisticChanged(); +    void goldChanged(); +    void silverChanged(); +    void bronzeChanged();  private:      int m_code;      QString m_name;      QString m_noc; +    QString m_mark; +    QString m_medalType; +    QString m_statistic; + +    int m_gold; +    int m_silver; +    int m_bronze;  }; diff --git a/src/model/CompetitorWithResults.cpp b/src/model/CompetitorWithResults.cpp deleted file mode 100644 index 70d9473..0000000 --- a/src/model/CompetitorWithResults.cpp +++ /dev/null @@ -1,61 +0,0 @@ - -#include "CompetitorWithResults.h" - -/** - * Replaces/sets the results of a competitor. - * - * @param results The results of the competitor. - * @return True, if successful. - */ -bool CompetitorWithResults::setResults(const QJsonObject &results) { -    if (!results.contains("m_mark") -        || !results.contains("m_medalType")) { -        return false; -    } - -    this->m_mark = results["m_mark"].toString(); -    this->m_medalType = results["m_medalType"].toString(); - -    return true; -} - -/** - * Static compare method, which can compare the result times or points of two CompetitorsWithResult. - * Returns true, if the left competitor (lComp) got a real lesser score than the right competitor (rComp). - * - * @param lComp First competitor to compare. - * @param rComp Second competitor to compare. - * @return True, if the second competitor got a higher score. - */ -bool CompetitorWithResults::compare(CompetitorWithResults lComp, CompetitorWithResults rComp) { -    QString l = lComp.getMark(); -    QString r = rComp.getMark(); - -    // check if values are numerical (-> not time values) -    if (!l.contains(":") || !r.contains(":")) { -        return l.toFloat() < r.toFloat(); -    } - -    // compare time values if not numerical -    QString lTime(""), rTime(""); - -    for (QChar c : l) if (c.isDigit()) lTime.append(c); -    for (QChar c : r) if (c.isDigit()) rTime.append(c); - -    return lTime.compare(rTime) < 0; -} - -bool CompetitorWithResults::setCompetitorWithResults(const QJsonObject &competitor) { -    setCompetitor(competitor); - -    if (!competitor.contains("results")) return false; -    QJsonObject results = competitor["results"].toObject(); -    return setResults(results); -} - -void CompetitorWithResults::setCompetitorWithResults(const CompetitorWithResults &competitor) { -    setCompetitor(competitor); -    setMark(competitor.m_mark); -    setMedalType(competitor.m_medalType); -    setStatistic(competitor.m_statistic); -} diff --git a/src/model/CompetitorWithResults.h b/src/model/CompetitorWithResults.h deleted file mode 100644 index a98a1e8..0000000 --- a/src/model/CompetitorWithResults.h +++ /dev/null @@ -1,40 +0,0 @@ - -#pragma once - -#include "Competitor.h" -#include <QString> -#include <QMap> -#include <QJsonObject> -#include <QObject> - -class CompetitorWithResults : public Competitor { - -     Q_OBJECT - -     Q_PROPERTY(QString mark READ mark NOTIFY nMark) -     Q_PROPERTY(QString medalType READ medalType NOTIFY nMedalType) -     Q_PROPERTY(QString statistic READ statistic NOTIFY nStatistic) - -public: -    explicit CompetitorWithResults(Competitor *parent) : Competitor(parent) {} - -    bool setResults(const QJsonObject &results); -    void setMark(QString mark) { this->m_mark = mark; } -    void setMedalType(QString medalType) { this->m_medalType = medalType; } -    void setStatistic(QString stat) { this->m_statistic = stat; } - -    bool setCompetitorWithResults(const QJsonObject &competitor); -    void setCompetitorWithResults(const CompetitorWithResults &competitor); - -    QString getMark() { return this->m_mark; } -    QString getMedalType() { return this->m_medalType; } -    QString getStatistic() { return this->m_statistic; } - -    static bool compare(CompetitorWithResults lComp, CompetitorWithResults rComp); - -private: -    QString m_mark; -    QString m_medalType; -    QString m_statistic; - -}; diff --git a/src/model/EventInfo.cpp b/src/model/EventInfo.cpp index e9ecd46..fef0fba 100644 --- a/src/model/EventInfo.cpp +++ b/src/model/EventInfo.cpp @@ -1,22 +1,21 @@ -#include <QObject>  #include "EventInfo.h"  EventInfo::EventInfo(QObject *parent) : QObject(parent) {  }  QString EventInfo::eventName() const { -  return m_eventName; +  return this->m_eventName;  }  void EventInfo::setEventName(const QString &newEventName) {    m_eventName = newEventName;  } -QList<QString> EventInfo::competitors() const { +QList<Competitor*> EventInfo::competitors() const {    return m_competitors;  } -void EventInfo::setCompetitors(const QList<QString> &newCompetitors) { -  m_competitors = newCompetitors; +void EventInfo::setCompetitors(const QList<Competitor*> &newCompetitors) { +  this->m_competitors = newCompetitors;  } diff --git a/src/model/EventInfo.h b/src/model/EventInfo.h index 7f937b2..def3885 100644 --- a/src/model/EventInfo.h +++ b/src/model/EventInfo.h @@ -1,28 +1,27 @@ -#ifndef ITAT_CHALLANGE_OLYMPICS_EVENT_H -#define ITAT_CHALLANGE_OLYMPICS_EVENT_H +#pragma once +#include "Competitor.h"  #include <QObject> +#include <QAbstractListModel>  #include <qqml.h> -class EventInfo : QObject { +class EventInfo : public QObject {    Q_OBJECT    // QML_ELEMENT -  Q_PROPERTY(QString eventName READ eventName WRITE setEventName); -  Q_PROPERTY(QList<QString> competitors READ competitors WRITE setCompetitors); +  Q_PROPERTY(QString eventName READ eventName CONSTANT) +  Q_PROPERTY(QList<Competitor*> competitors READ competitors CONSTANT) -  public: +public:    explicit EventInfo(QObject *parent = nullptr);    QString eventName() const;    void setEventName(const QString &newEventName); -  QList<QString> competitors() const; -  void setCompetitors(const QList<QString> &newCompetitors); +  QList<Competitor*> competitors() const; +  void setCompetitors(const QList<Competitor*> &newCompetitors); -  private: +private:    QString m_eventName; -  QList<QString> m_competitors; +  QList<Competitor*> m_competitors;  }; - -#endif  diff --git a/src/model/MedalWinner.cpp b/src/model/MedalWinner.cpp deleted file mode 100644 index 56cfb22..0000000 --- a/src/model/MedalWinner.cpp +++ /dev/null @@ -1,57 +0,0 @@ - -#include "MedalWinner.h" - -/** - * Replaces/sets the won medals of a competitor. - * - * @param medals The won medals with their amount. - * @return True, if successful. - */ -bool MedalWinner::setMedals(const QJsonObject &medals) { -    if (!medals.contains("ME_GOLD") -        || !medals.contains("ME_SILVER") -        || !medals.contains("ME_BRONZE")) { -        return false; -    } - -    setGold(medals["ME_GOLD"].toInt()); -    setSilver(medals["ME_SILVER"].toInt()); -    setBronze(medals["ME_BRONZE"].toInt()); - -    return true; -} - -/** - * Static compare method, which can compare the amount of medals of two MedalWinners. - * Gold has the highest priority, then m_silver and finally m_bronze. - * - * @param lComp First competitor to compare. - * @param rComp Second competitor to compare. - * @return True, if the second competitor got more or higher medals. - */ -bool MedalWinner::compare(MedalWinner lComp, MedalWinner rComp) { -    // create difference between medal amounts -    int gold = lComp.getGold() - rComp.getGold(); -    int silver = lComp.getSilver() - rComp.getSilver(); -    int bronze = lComp.getBronze() - rComp.getBronze(); - -    // compare medal differences -    return gold < 0 || (gold == 0 && (silver < 0 || (silver == 0 && bronze < 0))); -} - -bool MedalWinner::setMedalWinner(const QJsonObject &competitor) { -    setCompetitor(competitor); - -    if (!competitor.contains("medals")) return false; -    QJsonObject medals = competitor["medals"].toObject(); -    setMedals(medals); -    return true; -} - -void MedalWinner::setMedalWinner(const MedalWinner &competitor) { -    setCompetitor(competitor); - -    setGold(competitor.m_gold); -    setSilver(competitor.m_silver); -    setBronze(competitor.m_bronze); -} diff --git a/src/model/MedalWinner.h b/src/model/MedalWinner.h deleted file mode 100644 index 10d08bd..0000000 --- a/src/model/MedalWinner.h +++ /dev/null @@ -1,39 +0,0 @@ - -#pragma once - -#include "Competitor.h" -#include <QMap> -#include <QJsonObject> - -#include <QAbstractListModel> - -class MedalWinner : public Competitor { - -     Q_OBJECT - -     Q_PROPERTY(int gold READ m_gold NOTIFY nGold) -     Q_PROPERTY(int silver READ m_silver NOTIFY nSilver) -     Q_PROPERTY(int bronze READ m_bronze NOTIFY nBronze) - -public: -    explicit MedalWinner(Competitor *parent) : Competitor(parent) {} - -    bool setMedalWinner(const QJsonObject &competitor); -    void setMedalWinner(const MedalWinner &competitor); - -    bool setMedals(const QJsonObject &medals); - -    void setGold(int gold) { this->m_gold = gold; } -    void setSilver(int silver) { this->m_silver = silver; } -    void setBronze(int bronze) { this->m_bronze = bronze; } - -    int getGold() { return m_gold; } -    int getSilver() { return m_silver; } -    int getBronze() { return m_bronze; } - -    static bool compare(MedalWinner lComp, MedalWinner rComp); - -private: -    int m_gold, m_silver, m_bronze; - -}; diff --git a/src/model/SportModel.cpp b/src/model/SportModel.cpp index be9d326..557affe 100644 --- a/src/model/SportModel.cpp +++ b/src/model/SportModel.cpp @@ -8,8 +8,7 @@  #include <set>  // sorting and filtering -#include <map> -#include <algorithm> +//#include <algorithm>  #include <regex>  // float to string formatting @@ -42,7 +41,7 @@ QVariant SportModel::data(const QModelIndex &index, int role) const {          return event->eventName();        case Competitors: -        return event->competitors(); +        return QVariant::fromValue(event->competitors());      }    } @@ -82,14 +81,14 @@ void SportModel::parseData() {        qDeleteAll(m_sportList);        m_sportList.clear(); - -        QByteArray strReply = m_reply->readAll();        //parse json        // qDebug() << "Response:" << strReply;        QJsonDocument jsonDocument = QJsonDocument::fromJson(strReply); +      map<QString, map<QString, int>> medals = getMedalsOfCompetitors(); +        QJsonArray sports = jsonDocument["units"].toArray();        for (const auto &sport : sports) {          QJsonObject entry = sport.toObject(); @@ -97,15 +96,20 @@ void SportModel::parseData() {          EventInfo *event = new EventInfo(this);          event->setEventName(entry["eventUnitName"].toString()); -        QList<QString> competitors; +        QList<Competitor*> competitors;          for (const auto &competitor : entry["competitors"].toArray()) { -          competitors << competitor.toObject()["name"].toString(); +          Competitor *comp = new Competitor(this); +          comp->setCompetitor(competitor.toObject()); +          if (medals.find(comp->name()) != medals.end()) comp->setMedals(medals.find(comp->name())->second); +          if (!competitors.empty()) comp->setStatistic(competitors.first()->mark()); +          competitors << comp;          }          event->setCompetitors(competitors);          qDebug() << entry["eventUnitName"].toString();          m_sportList << event;        } +        endResetModel();      }  } @@ -134,7 +138,7 @@ void SportModel::lastName(QList<Competitor*> &competitors) {      for (int i = 0; i < competitors.size(); i++) {          Competitor* comp = competitors.value(i); -        string fullName = comp->getName().toUtf8().constData(); +        string fullName = comp->name().toUtf8().constData();          // regex to identify names, written in CAPS          regex r("[A-Z']{2,}"); @@ -185,43 +189,13 @@ set<QString> SportModel::getCategories() {  }  /** - * @brief Sport::getCompetitorsByCategory Searches for all competitors, who took part in the given category. - * @param category The category to search in. - * @return An QJsonArray with all competitors as QJsonValueRef, which can be casted to QJsonObject. - */ -QList<CompetitorWithResults*> SportModel::getCompetitorsByCategory(QString category) { -    QList<CompetitorWithResults*> competitors; - -    if (!validateDiscipline()) return competitors; - -    for (const QJsonValueRef &unitRef : this->o_discipline["units"].toArray()) { -        QJsonObject unit = unitRef.toObject(); - -        // validate unit -        if (!unit.contains("eventUnitName") || !unit.contains("competitors")) continue; - -        // search all units with the same category -        if (unit["eventUnitName"].toString().compare(category, Qt::CaseSensitive) != 0) continue; - -        // add all competitors from one unit -        for (const QJsonValueRef &compRef : unit["competitors"].toArray()) { -            CompetitorWithResults *comp = new CompetitorWithResults(); // TODO declare comp -            comp->setCompetitorWithResults(compRef.toObject()); -            competitors.push_back(comp); -        } -    } - -    return competitors; -} - -/** - * @brief Sport::getCompetitorsWithMedal Filters all competitors, who have at least one medal. These objects are different from getCompetitorsByCategory !!! + * @brief Sport::getMedalsOfCompetitor Filters all competitors, who have at least one medal. These objects are different from getCompetitorsByCategory !!!   * @return All competitors, who won at least one medal. Structure of one competitor: {code, name, m_noc, medals{ME_GOLD, ME_SILVER, ME_BRONZE}}   */ -QList<MedalWinner*> SportModel::getCompetitorsWithMedal() { -    map<QString, QJsonObject> competitors; +map<QString, map<QString, int>> SportModel::getMedalsOfCompetitors() { +    map<QString, map<QString, int>> competitors; -    if (!validateDiscipline()) return QList<MedalWinner*>(); +    if (!validateDiscipline()) return competitors;      // filter all units, which have medal events      QJsonArray units = filter(this->o_discipline["units"].toArray(), [](QJsonObject unit){ @@ -242,7 +216,7 @@ QList<MedalWinner*> SportModel::getCompetitorsWithMedal() {          QJsonArray medalComps = filter(unit["competitors"].toArray(), [](QJsonObject comp) {              if (!comp.contains("results")) return false; -            QString medalType = comp["results"].toObject()["m_medalType"].toString(); +            QString medalType = comp["results"].toObject()["medalType"].toString();              return !medalType.isEmpty();          }); @@ -252,65 +226,26 @@ QList<MedalWinner*> SportModel::getCompetitorsWithMedal() {              // validate competitor (with medal)              if (!medalComp.contains("name")                  || !medalComp.contains("results") -                || !medalComp["results"].toObject().contains("m_medalType")) continue; +                || !medalComp["results"].toObject().contains("medalType")) continue;              QString name = medalComp["name"].toString(); -            QString medalType = medalComp["results"].toObject()["m_medalType"].toString(); +            QString medalType = medalComp["results"].toObject()["medalType"].toString();              // check if competitor has other medal(s)              if (competitors.find(name) == competitors.end()) { -                competitors.insert({name, createCompetitorWithMedals(medalComp)}); +                map<QString, int> emptyMedalObject = { +                    {"ME_GOLD", 0}, +                    {"ME_SILVER", 0}, +                    {"ME_BRONZE", 0} +                }; +                competitors.insert({name, emptyMedalObject});              }              // update the medal count -            QJsonObject updatedMedalCount = QJsonObject(competitors.find(name)->second["medals"].toObject()); - -            int amount = updatedMedalCount[medalType].toInt() + 1; -            updatedMedalCount.remove(medalType); -            updatedMedalCount.insert(medalType, amount); - -            // create new medals QJsonObject and set it in the map -            competitors.find(name)->second["medals"] = updatedMedalCount; +            competitors.find(name)->second.find(medalType)->second++;          }      } - -    // convert map to QJsonArray -    QList<MedalWinner*> output; -    for (const pair<QString, QJsonObject> &competitor : competitors) { -        MedalWinner *comp = new MedalWinner(); // TODO declare comp -        comp->setMedalWinner(competitor.second); -        output.append(comp); -    } - -    return output; -} - -/** - * @brief Sport::createCompetitorWithMedals Creates a competitor QJsonObject with the following attributes: code, name, m_noc, medals{ME_GOLD, ME_SILVER, ME_BRONZE} - * @param comp The original competitor object. - * @return A competitor object with medal counts. - */ -QJsonObject SportModel::createCompetitorWithMedals(QJsonObject comp) { -    // repair competitor if something is missing -    if (!comp.contains("code")) comp.insert("code", "0"); -    if (!comp.contains("name")) comp.insert("code", ""); -    if (!comp.contains("m_noc")) comp.insert("code", ""); - -    // create new competitor QJsonObject and add it to the competitor map -    QJsonObject medals { -        {"ME_GOLD", 0}, -        {"ME_SILVER", 0}, -        {"ME_BRONZE", 0} -    }; - -    QJsonObject medalComp { -        {"code", comp["code"].toString()}, -        {"name", comp["name"].toString()}, -        {"m_noc", comp["m_noc"].toString()}, -        {"medals", medals} -    }; - -    return medalComp; +    return competitors;  }  /** @@ -339,7 +274,7 @@ void SportModel::filterByCountry(QList<Competitor*> &competitors, QString nocSho   */  void SportModel::filterCompetitors(QList<Competitor*> &competitors, QString filter) {      for (int i = 0; i < competitors.size(); i++) { -        if (!competitors.value(i)->getNOC().contains(filter)) { +        if (!competitors.value(i)->noc().contains(filter)) {              competitors.remove(i);              i--;          } @@ -350,37 +285,37 @@ void SportModel::filterCompetitors(QList<Competitor*> &competitors, QString filt   * @brief Sport::sortByName Sort the competitors by their name (alphabetical, ascending).   * @param competitors The competitors of one category.   */ -void SportModel::sortByName(QList<Competitor*> &competitors) { -    if (competitors.isEmpty()) return; -    std::sort(competitors.begin(), competitors.end(), Competitor::compareName); -} +//void SportModel::sortByName(QList<Competitor*> &competitors) { +//    if (competitors.isEmpty()) return; +//    std::sort(competitors.begin(), competitors.end(), Competitor::compareName); +//}  /**   * @brief Sport::sortByCountry Sort the competitors by their national olympic comittee short name (alphabetical, ascending).   * @param competitors The competitors of one category.   */ -void SportModel::sortByCountry(QList<Competitor*> &competitors) { -    if (competitors.isEmpty()) return; -    std::sort(competitors.begin(), competitors.end(), Competitor::compareNOC); -} +//void SportModel::sortByCountry(QList<Competitor*> &competitors) { +//    if (competitors.isEmpty()) return; +//    std::sort(competitors.begin(), competitors.end(), Competitor::compareNOC); +//}  /**   * @brief Sport::sortByResult Sort the competitors by their results in one specific category (numerical, ascending).   * @param competitors The competitors of one category.   */ -void SportModel::sortByResult(QList<CompetitorWithResults*> &competitors) { -    if (competitors.isEmpty()) return; -    std::sort(competitors.begin(), competitors.end(), CompetitorWithResults::compare); -} +//void SportModel::sortByResult(QList<Competitor*> &competitors) { +//    if (competitors.isEmpty()) return; +//    std::sort(competitors.begin(), competitors.end(), Competitor::compareMark); +//}  /**   * @brief Sport::sortByMedals Sort the competitors by their medal amounts in one specific category (numerical, ascending).   * @param competitors The competitors of one category.   */ -void SportModel::sortByMedals(QList<MedalWinner*> &competitors) { -    if (competitors.isEmpty()) return; -    std::sort(competitors.begin(), competitors.end(), MedalWinner::compare); -} +//void SportModel::sortByMedals(QList<Competitor*> &competitors) { +//    if (competitors.isEmpty()) return; +//    std::sort(competitors.begin(), competitors.end(), Competitor::compareMedals); +//}  /**   * @brief Sport::reverseOrder Reverses the order of the competitors. @@ -403,15 +338,15 @@ void SportModel::reverseOrder(QList<Competitor*> &competitors) {   * Stores the m_statistic in obj->results->stat for each competitor.   * @param competitors The competitors of one category.   */ -void SportModel::addRelativeToFirst(QList<CompetitorWithResults*> &competitors) { +void SportModel::addRelativeToFirst(QList<Competitor*> &competitors) {      if (competitors.isEmpty()) return; -    QString reference = competitors.value(0)->getMark(); +    QString reference = competitors.value(0)->mark();      for (int i = 0; i < competitors.size(); i++) { -        CompetitorWithResults *comp = competitors.value(i); +        Competitor *comp = competitors.value(i); -        QString result = comp->getMark(); +        QString result = comp->mark();          // format relative float value to string with 2 digits after decimal point and sign          stringstream sstream; diff --git a/src/model/SportModel.h b/src/model/SportModel.h index 5ad289c..a971b50 100644 --- a/src/model/SportModel.h +++ b/src/model/SportModel.h @@ -1,7 +1,5 @@  #pragma once -#include "MedalWinner.h" -#include "CompetitorWithResults.h"  #include <QAbstractListModel>  #include <QNetworkAccessManager>  #include <qcontainerfwd.h> @@ -40,23 +38,22 @@ public:    virtual QHash<int, QByteArray> roleNames() const override;    set<QString> getCategories(); -  QList<CompetitorWithResults*> getCompetitorsByCategory(QString category); // TODO ref instead of obj -  QList<MedalWinner*> getCompetitorsWithMedal(); // TODO ref instead of obj +  map<QString, map<QString, int>> getMedalsOfCompetitors();    // filter to change the current competitor list -  void lastName(QList<Competitor*> &competitors); // TODO ref instead of obj -  void filterByName(QList<Competitor*> &competitors, QString name); // TODO ref instead of obj -  void filterByCountry(QList<Competitor*> &competitors, QString nocShort); // TODO ref instead of obj +  void lastName(QList<Competitor*> &competitors); +  void filterByName(QList<Competitor*> &competitors, QString name); +  void filterByCountry(QList<Competitor*> &competitors, QString nocShort);    // sort functions to change the order of the current competitor list -  void sortByName(QList<Competitor*> &competitors); // TODO ref instead of obj -  void sortByCountry(QList<Competitor*> &competitors); // TODO ref instead of obj -  void sortByResult(QList<CompetitorWithResults*> &competitors); // TODO ref instead of obj -  void sortByMedals(QList<MedalWinner*> &competitors); // TODO ref instead of obj -  void reverseOrder(QList<Competitor*> &competitors); // TODO ref instead of obj +//  void sortByName(QList<Competitor*> &competitors); +//  void sortByCountry(QList<Competitor*> &competitors); +//  void sortByResult(QList<Competitor*> &competitors); +//  void sortByMedals(QList<Competitor*> &competitors); +  void reverseOrder(QList<Competitor*> &competitors);    // statistic function -  void addRelativeToFirst(QList<CompetitorWithResults*> &competitors); // TODO ref instead of obj +  void addRelativeToFirst(QList<Competitor*> &competitors);    QString discipline() const;    void setDiscipline(const QString &discipline); @@ -80,8 +77,6 @@ private:    void filterCompetitors(QList<Competitor*> &competitors, QString filter); // TODO ref instead of obj -  QJsonObject createCompetitorWithMedals(QJsonObject medalComp); -    // function for statistic calculation    float calcRelativeStat(QString ref, QString val); | 
