From 942e0b22f9707b7f2e09b0d4d1419aa5c31487aa Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Sun, 20 May 2018 13:48:37 +0200 Subject: [PATCH] Also show power plug incompatibilities in the country information elements So far this only considers total incompatibilities (e.g. EU <-> GB) but does not yet detect partial incompatibilities (e.g. EU <-> CH). --- autotests/timelinemodeltest.cpp | 30 +++++++++++----- src/app/CountryInfoDelegate.qml | 6 ++++ src/app/countryinformation.cpp | 61 +++++++++++++++++++++++++++++++-- src/app/countryinformation.h | 11 ++++++ src/app/timelinemodel.cpp | 29 ++++++++++------ src/app/timelinemodel.h | 1 + 6 files changed, 117 insertions(+), 21 deletions(-) diff --git a/autotests/timelinemodeltest.cpp b/autotests/timelinemodeltest.cpp index 9724c32..5160782 100644 --- a/autotests/timelinemodeltest.cpp +++ b/autotests/timelinemodeltest.cpp @@ -151,22 +151,36 @@ private slots: QCOMPARE(model.index(0, 0).data(TimelineModel::ElementTypeRole), TimelineModel::TodayMarker); resMgr.importReservation(QUrl::fromLocalFile(QLatin1String(SOURCE_DIR "/data/flight-txl-lhr-sfo.json"))); - QCOMPARE(model.rowCount(), 4); // GB country info, 2 flights, today marker + QCOMPARE(model.rowCount(), 5); // 2x country info, 2x flights, today marker + QCOMPARE(model.index(0, 0).data(TimelineModel::ElementTypeRole), TimelineModel::CountryInfo); auto countryInfo = model.index(0, 0).data(TimelineModel::CountryInformationRole).value(); - qDebug() << (int)countryInfo.drivingSide() << countryInfo.drivingSideDiffers(); QCOMPARE(countryInfo.drivingSide(), KItinerary::KnowledgeDb::DrivingSide::Left); QCOMPARE(countryInfo.drivingSideDiffers(), true); + QCOMPARE(countryInfo.powerPlugTypesDiffer(), true); QCOMPARE(model.index(1, 0).data(TimelineModel::ElementTypeRole), TimelineModel::Flight); - QCOMPARE(model.index(2, 0).data(TimelineModel::ElementTypeRole), TimelineModel::Flight); - QCOMPARE(model.index(3, 0).data(TimelineModel::ElementTypeRole), TimelineModel::TodayMarker); - // remove the GB flight, should also remove the GB country info + QCOMPARE(model.index(2, 0).data(TimelineModel::ElementTypeRole), TimelineModel::CountryInfo); + countryInfo = model.index(2, 0).data(TimelineModel::CountryInformationRole).value(); + QCOMPARE(countryInfo.drivingSide(), KItinerary::KnowledgeDb::DrivingSide::Right); + QCOMPARE(countryInfo.drivingSideDiffers(), false); + QCOMPARE(countryInfo.powerPlugTypesDiffer(), true); + QCOMPARE(model.index(3, 0).data(TimelineModel::ElementTypeRole), TimelineModel::Flight); + QCOMPARE(model.index(4, 0).data(TimelineModel::ElementTypeRole), TimelineModel::TodayMarker); + + // remove the GB flight should also remove the GB country info auto resId = model.index(1, 0).data(TimelineModel::ReservationIdRole).toString(); resMgr.removeReservation(resId); - QCOMPARE(model.rowCount(), 2); - QCOMPARE(model.index(0, 0).data(TimelineModel::ElementTypeRole), TimelineModel::Flight); - QCOMPARE(model.index(1, 0).data(TimelineModel::ElementTypeRole), TimelineModel::TodayMarker); + QCOMPARE(model.rowCount(), 3); + QCOMPARE(model.index(0, 0).data(TimelineModel::ElementTypeRole), TimelineModel::CountryInfo); + QCOMPARE(model.index(1, 0).data(TimelineModel::ElementTypeRole), TimelineModel::Flight); + QCOMPARE(model.index(2, 0).data(TimelineModel::ElementTypeRole), TimelineModel::TodayMarker); + + // remove the US flight should also remove the US country info + resId = model.index(1, 0).data(TimelineModel::ReservationIdRole).toString(); + resMgr.removeReservation(resId); + QCOMPARE(model.rowCount(), 1); + QCOMPARE(model.index(0, 0).data(TimelineModel::ElementTypeRole), TimelineModel::TodayMarker); } }; diff --git a/src/app/CountryInfoDelegate.qml b/src/app/CountryInfoDelegate.qml index 142a9fa..da567c0 100644 --- a/src/app/CountryInfoDelegate.qml +++ b/src/app/CountryInfoDelegate.qml @@ -59,6 +59,12 @@ Kirigami.AbstractCard { color: Kirigami.Theme.negativeTextColor visible: countryInfo.drivingSideDiffers } + + QQC2.Label { + text: qsTr("Incompatible power plugs: %1").arg(countryInfo.powerPlugTypes) + color: Kirigami.Theme.negativeTextColor + visible: countryInfo.powerPlugTypesDiffer + } } } diff --git a/src/app/countryinformation.cpp b/src/app/countryinformation.cpp index bf102fe..f70548e 100644 --- a/src/app/countryinformation.cpp +++ b/src/app/countryinformation.cpp @@ -17,6 +17,8 @@ #include "countryinformation.h" +#include + #include using namespace KItinerary; @@ -29,7 +31,10 @@ CountryInformation::~CountryInformation() = default; bool CountryInformation::operator==(const CountryInformation& other) const { - return m_drivingSide == other.m_drivingSide || m_drivingSide == KnowledgeDb::DrivingSide::Unknown || other.m_drivingSide == KnowledgeDb::DrivingSide::Unknown; + const auto dsEqual = m_drivingSide == other.m_drivingSide || m_drivingSide == KnowledgeDb::DrivingSide::Unknown || other.m_drivingSide == KnowledgeDb::DrivingSide::Unknown; + const auto ppEqual = (m_powerPlugs & other.m_powerPlugs) || m_powerPlugs == KnowledgeDb::Unknown || other.m_powerPlugs == KnowledgeDb::Unknown; + + return dsEqual && ppEqual; } QString CountryInformation::isoCode() const @@ -50,7 +55,7 @@ void CountryInformation::setIsoCode(const QString& isoCode) } const auto countryRecord = KnowledgeDb::countryForId(id); setDrivingSide(countryRecord.drivingSide); - + setPowerPlugTypes(countryRecord.powerPlugTypes); } KnowledgeDb::DrivingSide CountryInformation::drivingSide() const @@ -71,7 +76,59 @@ void CountryInformation::setDrivingSide(KnowledgeDb::DrivingSide drivingSide) m_drivingSide = drivingSide; } +struct plugTypeName { + KnowledgeDb::PowerPlugType type; + const char *name; +} + +static const plug_name_table[] = { + { KnowledgeDb::TypeA, I18N_NOOP("Type A") }, + { KnowledgeDb::TypeB, I18N_NOOP("Type B") }, + { KnowledgeDb::TypeC, I18N_NOOP("Europlug") }, + { KnowledgeDb::TypeD, I18N_NOOP("Type D") }, + { KnowledgeDb::TypeE, I18N_NOOP("Type E") }, + { KnowledgeDb::TypeF, I18N_NOOP("Schuko") }, + { KnowledgeDb::TypeG, I18N_NOOP("Type G") }, + { KnowledgeDb::TypeH, I18N_NOOP("Type H") }, + { KnowledgeDb::TypeI, I18N_NOOP("Type I") }, + { KnowledgeDb::TypeJ, I18N_NOOP("Type J") }, + { KnowledgeDb::TypeK, I18N_NOOP("Type K") }, + { KnowledgeDb::TypeL, I18N_NOOP("Type L") }, + { KnowledgeDb::TypeM, I18N_NOOP("Type M") }, + { KnowledgeDb::TypeN, I18N_NOOP("Type N") }, +}; + +QString CountryInformation::powerPlugTypes() const +{ + QStringList l; + for (const auto &elem : plug_name_table) { + if (m_powerPlugs & elem.type) { + l.push_back(i18n(elem.name)); + } + } + return l.join(QLatin1String(", ")); +} + +void CountryInformation::setPowerPlugTypes(KItinerary::KnowledgeDb::PowerPlugTypes powerPlugs) +{ + // TODO deal with partial incompatibilities and compatibilities between plug types + if (m_powerPlugs == powerPlugs || powerPlugs == KnowledgeDb::Unknown) { + return; + } + + if ((m_powerPlugs & powerPlugs) == 0) { + m_powerPlugTypesDiffer = true; + } + + m_powerPlugs = powerPlugs; +} + bool CountryInformation::drivingSideDiffers() const { return m_drivingSideDiffers; } + +bool CountryInformation::powerPlugTypesDiffer() const +{ + return m_powerPlugTypesDiffer; +} diff --git a/src/app/countryinformation.h b/src/app/countryinformation.h index fd43e12..fadf436 100644 --- a/src/app/countryinformation.h +++ b/src/app/countryinformation.h @@ -28,9 +28,14 @@ class CountryInformation { Q_GADGET Q_PROPERTY(QString isoCode READ isoCode) + Q_PROPERTY(KItinerary::KnowledgeDb::DrivingSide drivingSide READ drivingSide) /** This indicates that the driving side information changed and needs to be displayed. */ Q_PROPERTY(bool drivingSideDiffers READ drivingSideDiffers) + + Q_PROPERTY(QString powerPlugTypes READ powerPlugTypes) + Q_PROPERTY(bool powerPlugTypesDiffer READ powerPlugTypesDiffer) + public: CountryInformation(); ~CountryInformation(); @@ -43,12 +48,18 @@ public: KItinerary::KnowledgeDb::DrivingSide drivingSide() const; bool drivingSideDiffers() const; + QString powerPlugTypes() const; + bool powerPlugTypesDiffer() const; + private: void setDrivingSide(KItinerary::KnowledgeDb::DrivingSide drivingSide); + void setPowerPlugTypes(KItinerary::KnowledgeDb::PowerPlugTypes powerPlugs); QString m_isoCode; + KItinerary::KnowledgeDb::PowerPlugTypes m_powerPlugs = KItinerary::KnowledgeDb::Unknown; KItinerary::KnowledgeDb::DrivingSide m_drivingSide = KItinerary::KnowledgeDb::DrivingSide::Unknown; bool m_drivingSideDiffers = false; + bool m_powerPlugTypesDiffer = false; }; Q_DECLARE_METATYPE(CountryInformation) diff --git a/src/app/timelinemodel.cpp b/src/app/timelinemodel.cpp index 6a48b7f..b7feeaa 100644 --- a/src/app/timelinemodel.cpp +++ b/src/app/timelinemodel.cpp @@ -318,15 +318,17 @@ void TimelineModel::updateInformationElements() for (auto it = m_elements.begin(); it != m_elements.end(); ++it) { switch ((*it).elementType) { case TodayMarker: + it = erasePreviousCountyInfo(it); continue; case CountryInfo: previousCountry = (*it).content.value(); + it = erasePreviousCountyInfo(it); // purge multiple consecutive country info elements continue; default: break; } - auto newCountry = previousCountry; + auto newCountry = homeCountry; newCountry.setIsoCode(destinationCountry(m_resMgr->reservation((*it).id))); if (newCountry == previousCountry) { continue; @@ -334,16 +336,8 @@ void TimelineModel::updateInformationElements() if (newCountry == homeCountry) { assert(it != m_elements.begin()); // previousCountry == homeCountry in this case // purge outdated country info element - auto it2 = it; - --it2; - if ((*it2).elementType == CountryInfo) { - auto row = std::distance(m_elements.begin(), it2); - beginRemoveRows({}, row, row); - it = m_elements.erase(it2); - endRemoveRows(); - previousCountry = newCountry; - } - + it = erasePreviousCountyInfo(it); + previousCountry = newCountry; continue; } @@ -356,3 +350,16 @@ void TimelineModel::updateInformationElements() previousCountry = newCountry; } } + +std::vector::iterator TimelineModel::erasePreviousCountyInfo(std::vector::iterator it) +{ + auto it2 = it; + --it2; + if ((*it2).elementType == CountryInfo) { + auto row = std::distance(m_elements.begin(), it2); + beginRemoveRows({}, row, row); + it = m_elements.erase(it2); + endRemoveRows(); + } + return it; +} diff --git a/src/app/timelinemodel.h b/src/app/timelinemodel.h index f30bb28..fd79a44 100644 --- a/src/app/timelinemodel.h +++ b/src/app/timelinemodel.h @@ -94,6 +94,7 @@ private: void reservationRemoved(const QString &resId); void updateInformationElements(); + std::vector::iterator erasePreviousCountyInfo(std::vector::iterator it); PkPassManager *m_passMgr = nullptr; ReservationManager *m_resMgr = nullptr; -- GitLab