Commit 87e40914 authored by Volker Krause's avatar Volker Krause
Browse files

Allow the platform model to match platforms on all their properties

We now have full Platform objects in the API, rather than hardcoding name
and mode in the setter. For this to work as expected from QML we need to
defer matching to the next event loop run though.

This also adds matching by IFOPT when present, which gives us a reliable
match even when the name is off.
parent b818f557
Pipeline #96886 skipped
......@@ -10,6 +10,7 @@
#include <QTest>
#include <QAbstractItemModelTester>
#include <QSignalSpy>
using namespace KOSMIndoorMap;
......@@ -33,10 +34,16 @@ private Q_SLOTS:
PlatformModel model;
QAbstractItemModelTester modelTest(&model);
QSignalSpy platformChangeSpy(&model, &PlatformModel::platformIndexChanged);
model.setMapData(mapData);
model.setArrivalPlatform(QStringLiteral("10"), Platform::Rail);
model.setDeparturePlatform(QStringLiteral("7"), Platform::Rail);
Platform p;
p.setMode(Platform::Rail);
p.setName(QStringLiteral("10"));
model.setArrivalPlatform(p);
p.setName(QStringLiteral("7"));
model.setDeparturePlatform(p);
QVERIFY(platformChangeSpy.wait());
QCOMPARE(model.rowCount(), 12);
for (int i = 0; i < model.rowCount(); ++i) {
......@@ -57,17 +64,22 @@ private Q_SLOTS:
QVERIFY(model.arrivalPlatformRow() >= 0);
// fuzzy platform matching
model.setArrivalPlatform(QStringLiteral("10 D-F"), Platform::Rail);
model.setDeparturePlatform(QStringLiteral("9A-C"), Platform::Rail);
p.setName(QStringLiteral("10 D-F"));
model.setArrivalPlatform(p);
p.setName(QStringLiteral("9A-C"));
model.setDeparturePlatform(p);
QVERIFY(platformChangeSpy.wait());
QVERIFY(model.departurePlatformRow() >= 0);
QVERIFY(model.arrivalPlatformRow() >= 0);
// non-matching platforms
model.setArrivalPlatform(QStringLiteral("13"), Platform::Rail);
model.setDeparturePlatform(QStringLiteral("14 A-D"), Platform::Rail);
p.setName(QStringLiteral("13"));
model.setArrivalPlatform(p);
p.setName(QStringLiteral("14 A-D"));
model.setDeparturePlatform(p);
QVERIFY(platformChangeSpy.wait());
QCOMPARE(model.departurePlatformRow(), -1);
QCOMPARE(model.arrivalPlatformRow(), -1);
}
};
......
......@@ -19,6 +19,13 @@ static constexpr auto TOP_PARENT = std::numeric_limits<quintptr>::max();
PlatformModel::PlatformModel(QObject* parent) :
QAbstractItemModel(parent)
{
m_matchTimer.setSingleShot(true);
m_matchTimer.setInterval(0);
connect(&m_matchTimer, &QTimer::timeout, this, &PlatformModel::matchPlatforms);
connect(this, &PlatformModel::mapDataChanged, &m_matchTimer, qOverload<>(&QTimer::start));
connect(this, &PlatformModel::arrivalPlatformChanged, &m_matchTimer, qOverload<>(&QTimer::start));
connect(this, &PlatformModel::departurePlatformChanged, &m_matchTimer, qOverload<>(&QTimer::start));
}
PlatformModel::~PlatformModel() = default;
......@@ -38,6 +45,8 @@ void PlatformModel::setMapData(const MapData &data)
m_platforms.clear();
m_platformLabels.clear();
m_sectionsLabels.clear();
m_arrivalPlatformRow = -1;
m_departurePlatformRow = -1;
m_data = data;
if (!m_data.isEmpty()) {
......@@ -50,7 +59,7 @@ void PlatformModel::setMapData(const MapData &data)
}
endResetModel();
Q_EMIT mapDataChanged();
matchPlatforms();
Q_EMIT platformIndexChanged();
}
bool PlatformModel::isEmpty() const
......@@ -146,18 +155,40 @@ QHash<int, QByteArray> PlatformModel::roleNames() const
return n;
}
Platform PlatformModel::arrivalPlatform() const
{
return m_arrivalPlatform;
}
void PlatformModel::setArrivalPlatform(const Platform &platform)
{
m_arrivalPlatform = platform;
Q_EMIT arrivalPlatformChanged();
}
void PlatformModel::setArrivalPlatform(const QString &name, Platform::Mode mode)
{
m_arrivalPlatform.setName(name);
m_arrivalPlatform.setMode(mode);
matchPlatforms();
Q_EMIT arrivalPlatformChanged();
}
Platform PlatformModel::departurePlatform() const
{
return m_departurePlatform;
}
void PlatformModel::setDeparturePlatform(const Platform &platform)
{
m_departurePlatform = platform;
Q_EMIT departurePlatformChanged();
}
void PlatformModel::setDeparturePlatform(const QString &name, Platform::Mode mode)
{
m_departurePlatform.setName(name);
m_departurePlatform.setMode(mode);
matchPlatforms();
Q_EMIT departurePlatformChanged();
}
int PlatformModel::arrivalPlatformRow() const
......@@ -201,6 +232,15 @@ static bool isPossiblySamePlatformName(const QString &name, const QString &platf
int PlatformModel::matchPlatform(const Platform &platform) const
{
if (!platform.ifopt().isEmpty()) { // try IFOPT first, if we have that
const auto it = std::find_if(m_platforms.begin(), m_platforms.end(), [platform](const auto &p) {
return p.ifopt() == platform.ifopt();
});
if (it != m_platforms.end()) {
return std::distance(m_platforms.begin(), it);
}
}
if (platform.name().isEmpty()) {
return -1;
}
......
......@@ -9,11 +9,11 @@
#include "kosmindoormap_export.h"
#include "platform.h"
#include <KOSMIndoorMap/MapData>
#include <KOSMIndoorMap/Platform>
#include <QAbstractItemModel>
#include <QTimer>
namespace KOSMIndoorMap {
......@@ -30,6 +30,11 @@ class KOSMINDOORMAP_EXPORT PlatformModel : public QAbstractItemModel
/** Row indexes of the matched arrival/departure platforms, if found and/or set, otherwise @c -1. */
Q_PROPERTY(int arrivalPlatformRow READ arrivalPlatformRow NOTIFY platformIndexChanged)
Q_PROPERTY(int departurePlatformRow READ departurePlatformRow NOTIFY platformIndexChanged)
/** Platform search parameters (name/mode/ifopt) for matching arrival/departure platform against what we found in the map data. */
Q_PROPERTY(KOSMIndoorMap::Platform arrivalPlatform READ arrivalPlatform WRITE setArrivalPlatform NOTIFY arrivalPlatformChanged)
Q_PROPERTY(KOSMIndoorMap::Platform departurePlatform READ departurePlatform WRITE setDeparturePlatform NOTIFY departurePlatformChanged)
public:
explicit PlatformModel(QObject *parent = nullptr);
~PlatformModel();
......@@ -58,8 +63,12 @@ public:
QHash<int, QByteArray> roleNames() const override;
/** Match arrival/departure platform against what we found in the map data. */
Q_INVOKABLE void setArrivalPlatform(const QString &name, KOSMIndoorMap::Platform::Mode mode);
Q_INVOKABLE void setDeparturePlatform(const QString &name, KOSMIndoorMap::Platform::Mode mode);
Platform arrivalPlatform() const;
void setArrivalPlatform(const Platform &platform);
Q_INVOKABLE [[deprecated("use arrivalPlatform property")]] void setArrivalPlatform(const QString &name, KOSMIndoorMap::Platform::Mode mode);
Platform departurePlatform() const;
void setDeparturePlatform(const Platform &platform);
Q_INVOKABLE [[deprecated("use departurePlatform property")]] void setDeparturePlatform(const QString &name, KOSMIndoorMap::Platform::Mode mode);
int arrivalPlatformRow() const;
int departurePlatformRow() const;
......@@ -67,6 +76,8 @@ public:
Q_SIGNALS:
void mapDataChanged();
void platformIndexChanged();
void arrivalPlatformChanged();
void departurePlatformChanged();
private:
void matchPlatforms();
......@@ -88,6 +99,8 @@ private:
Platform m_departurePlatform;
int m_arrivalPlatformRow = -1;
int m_departurePlatformRow = -1;
QTimer m_matchTimer;
};
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment