From 5c3d2f77f5d0dc56bf95af2a6c98398b73fda008 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Thu, 21 May 2015 01:09:17 +0200 Subject: [PATCH 01/85] Fix for QObject* ownership bugs Due to returning QObject* in calls to C++ objects from QML (e.g. getItem(i)), those objects were changing ownership to QML and were subject to gc. That could've been noticed during switching between journey results and journey details results (instantly switch back and forth to create enough garbage). `var item = result.getItem(i);` `item` would be null after some time. So it was ending up in page showing loader and not doing anything or in a bit more rare cases with segfault. --- rpm/harbour-fahrplan2.yaml | 2 ++ src/parser/parser_definitions.cpp | 9 +++++++++ src/parser/parser_definitions.h | 2 ++ src/parser/parser_efa.cpp | 4 ++-- src/parser/parser_hafasbinary.cpp | 4 ++-- src/parser/parser_hafasxml.cpp | 4 ++-- src/parser/parser_xmlvasttrafikse.cpp | 4 ++-- 7 files changed, 21 insertions(+), 8 deletions(-) diff --git a/rpm/harbour-fahrplan2.yaml b/rpm/harbour-fahrplan2.yaml index fc5836da..d0c023b1 100644 --- a/rpm/harbour-fahrplan2.yaml +++ b/rpm/harbour-fahrplan2.yaml @@ -15,8 +15,10 @@ PkgConfigBR: - Qt5Quick - Qt5Qml - Qt5Core +- sailfishapp Requires: - sailfishsilica-qt5 >= 0.10.9 +- qt5-qtdeclarative-import-positioning Files: - '%{_datadir}/icons/hicolor/86x86/apps/%{name}.png' - '%{_datadir}/applications/%{name}.desktop' diff --git a/src/parser/parser_definitions.cpp b/src/parser/parser_definitions.cpp index 13363e72..970fcce5 100644 --- a/src/parser/parser_definitions.cpp +++ b/src/parser/parser_definitions.cpp @@ -127,6 +127,10 @@ void JourneyResultList::setTimeInfo(const QString &timeInfo) } //------------- JourneyResultItem +JourneyResultItem::JourneyResultItem(QObject *parent) : QObject(parent) +{ + +} QString JourneyResultItem::id() const { @@ -327,6 +331,11 @@ void JourneyDetailResultList::setDuration(const QString &duration) //------------- JourneyDetailResultItem +JourneyDetailResultItem::JourneyDetailResultItem(QObject *parent) : QObject(parent) +{ + +} + QString JourneyDetailResultItem::departureStation() const { return m_departureStation; diff --git a/src/parser/parser_definitions.h b/src/parser/parser_definitions.h index 7587c1ab..94278a1e 100644 --- a/src/parser/parser_definitions.h +++ b/src/parser/parser_definitions.h @@ -95,6 +95,7 @@ class JourneyResultItem : public QObject Q_PROPERTY(QString internalData2 READ internalData2 WRITE setInternalData2) public: + explicit JourneyResultItem(QObject * parent = 0); QString id() const; void setId(const QString &); QDate date() const; @@ -176,6 +177,7 @@ class JourneyDetailResultItem : public QObject Q_PROPERTY(QString internalData1 READ internalData1 WRITE setInternalData1) Q_PROPERTY(QString internalData2 READ internalData2 WRITE setInternalData2) public: + explicit JourneyDetailResultItem(QObject * parent = 0); QString departureStation() const; void setDepartureStation(const QString &); QString departureInfo() const; diff --git a/src/parser/parser_efa.cpp b/src/parser/parser_efa.cpp index d934be35..0ed6c2b5 100755 --- a/src/parser/parser_efa.cpp +++ b/src/parser/parser_efa.cpp @@ -542,7 +542,7 @@ void ParserEFA::parseSearchJourney(QNetworkReply *networkReply) info = tr("Guaranteed connection"); } motNameList.append(motName); - JourneyDetailResultItem *jdrItem = new JourneyDetailResultItem(); + JourneyDetailResultItem *jdrItem = new JourneyDetailResultItem(detailsList); jdrItem->setTrain(motName); jdrItem->setInfo(info); jdrItem->setDirection(motElement.attribute("destination")); @@ -580,7 +580,7 @@ void ParserEFA::parseSearchJourney(QNetworkReply *networkReply) detailsList->setDepartureDateTime(departureDateTime); cachedJourneyDetailsEfa[id] = detailsList; - JourneyResultItem *item = new JourneyResultItem(); + JourneyResultItem *item = new JourneyResultItem(lastJourneyResultList); item->setDate(departureDateTime.date()); item->setId(id); item->setTransfers(changes); diff --git a/src/parser/parser_hafasbinary.cpp b/src/parser/parser_hafasbinary.cpp index 8568a175..7fafab07 100644 --- a/src/parser/parser_hafasbinary.cpp +++ b/src/parser/parser_hafasbinary.cpp @@ -328,7 +328,7 @@ void ParserHafasBinary::parseSearchJourney(QNetworkReply *networkReply) for (int iPart = 0; iPart < numParts; iPart++) { - JourneyDetailResultItem *inlineItem = new JourneyDetailResultItem(); + JourneyDetailResultItem *inlineItem = new JourneyDetailResultItem(inlineResults); hafasData.device()->seek(0x4a + partsOffset + iPart * 20); @@ -571,7 +571,7 @@ void ParserHafasBinary::parseSearchJourney(QNetworkReply *networkReply) lineNames.removeDuplicates(); - JourneyResultItem *item = new JourneyResultItem(); + JourneyResultItem *item = new JourneyResultItem(lastJourneyResultList); item->setDate(journeyDate); item->setId(connectionId); item->setTransfers(QString::number(numChanges)); diff --git a/src/parser/parser_hafasxml.cpp b/src/parser/parser_hafasxml.cpp index ee129b3c..b110c62b 100644 --- a/src/parser/parser_hafasxml.cpp +++ b/src/parser/parser_hafasxml.cpp @@ -656,7 +656,7 @@ void ParserHafasXml::parseSearchJourney(QNetworkReply *networkReply) const QDomNodeList connections = doc.elementsByTagName("Connection"); for (int i = 0; i < connections.count(); ++i) { - JourneyResultItem *item = new JourneyResultItem(); + JourneyResultItem *item = new JourneyResultItem(lastJourneyResultList); item->setId(connections.at(i).toElement().attribute("id").trimmed()); QDomElement overview = connections.at(i).firstChildElement("Overview"); @@ -846,7 +846,7 @@ JourneyDetailResultList* ParserHafasXml::internalParseJourneyDetails(const QDomE const QDomNodeList sections = connection.elementsByTagName("ConSection"); for (int i = 0; i < sections.count(); ++i) { - JourneyDetailResultItem *item = new JourneyDetailResultItem(); + JourneyDetailResultItem *item = new JourneyDetailResultItem(results); const QDomNode section = sections.at(i); QDomElement stop; diff --git a/src/parser/parser_xmlvasttrafikse.cpp b/src/parser/parser_xmlvasttrafikse.cpp index 75534115..f702413c 100644 --- a/src/parser/parser_xmlvasttrafikse.cpp +++ b/src/parser/parser_xmlvasttrafikse.cpp @@ -329,7 +329,7 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) if (doc.setContent(xmlRawtext, false)) { QDomNodeList tripNodeList = doc.elementsByTagName("Trip"); for (unsigned int i = 0; i < tripNodeList.length(); ++i) { - JourneyResultItem *jritem = new JourneyResultItem(); + JourneyResultItem *jritem = new JourneyResultItem(journeyResultList); JourneyDetailResultList *detailsList = new JourneyDetailResultList(); /// Set default values for journey's start and end time @@ -367,7 +367,7 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) trainTypes.append(i18nConnectionType(getAttribute(legNode, "name"))); } - JourneyDetailResultItem *jdrItem = new JourneyDetailResultItem(); + JourneyDetailResultItem *jdrItem = new JourneyDetailResultItem(detailsList); jdrItem->setDepartureStation(getAttribute(originNode, "name")); const QString depTrack = getAttribute(originNode, "track"); jdrItem->setDepartureInfo(depTrack.isEmpty() ? QChar(0x2014) : tr("Track %1").arg(depTrack)); From 759160236e60a0d18d91e6d2aa2d5bdf76e31c1f Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 25 May 2015 00:46:48 +0200 Subject: [PATCH 02/85] added missed parents --- src/parser/parser_ninetwo.cpp | 4 ++-- src/parser/parser_resrobot.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/parser/parser_ninetwo.cpp b/src/parser/parser_ninetwo.cpp index b5194782..b92f161c 100644 --- a/src/parser/parser_ninetwo.cpp +++ b/src/parser/parser_ninetwo.cpp @@ -291,7 +291,7 @@ void ParserNinetwo::parseSearchJourney(QNetworkReply *networkReply) for (i = journeys.constBegin(); i != journeys.constEnd(); ++i) { QVariantMap journey = i->toMap(); parseJourneyOption(journey); - JourneyResultItem* item = new JourneyResultItem; + JourneyResultItem* item = new JourneyResultItem(result); arrival = QDateTime::fromString(journey.value("arrival").toString(), "yyyy-MM-ddTHH:mm"); departure = QDateTime::fromString(journey.value("departure").toString(), "yyyy-MM-ddTHH:mm"); @@ -373,7 +373,7 @@ void ParserNinetwo::parseJourneyOption(const QVariantMap &object) for(int i = 0; i < legs.count(); i++) { QVariantMap leg = legs.at(i).toMap(); - JourneyDetailResultItem* resultItem = new JourneyDetailResultItem; + JourneyDetailResultItem* resultItem = new JourneyDetailResultItem(result); QVariantList stops = leg.value("stops").toList(); diff --git a/src/parser/parser_resrobot.cpp b/src/parser/parser_resrobot.cpp index c0fbc0cb..40e97a56 100644 --- a/src/parser/parser_resrobot.cpp +++ b/src/parser/parser_resrobot.cpp @@ -479,7 +479,7 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) else if (arrDayDiff < 0) arrTime += QString::number(arrDayDiff); - JourneyResultItem* journey = new JourneyResultItem; + JourneyResultItem* journey = new JourneyResultItem(result); journey->setId(journeyID); journey->setDate(segments.first()->departureDateTime().date()); journey->setDepartureTime(depTime); @@ -523,7 +523,7 @@ QList ParserResRobot::parseJourneySegments(const QVari foreach (QVariant segmentData, segments) { QVariantMap segment = segmentData.toMap(); - JourneyDetailResultItem* resultItem = new JourneyDetailResultItem; + JourneyDetailResultItem* resultItem = new JourneyDetailResultItem(results); // Departure QVariantMap departure = segment.value("departure").toMap(); From f3b8e77cef237974f636f2f6100a2e604c4bea6f Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 25 May 2015 01:02:20 +0200 Subject: [PATCH 03/85] not that easy there, leaving a FIXME for the next round --- src/parser/parser_resrobot.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/parser/parser_resrobot.cpp b/src/parser/parser_resrobot.cpp index 40e97a56..f2b1b1ab 100644 --- a/src/parser/parser_resrobot.cpp +++ b/src/parser/parser_resrobot.cpp @@ -479,7 +479,7 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) else if (arrDayDiff < 0) arrTime += QString::number(arrDayDiff); - JourneyResultItem* journey = new JourneyResultItem(result); + JourneyResultItem* journey = new JourneyResultItem(journeyList); journey->setId(journeyID); journey->setDate(segments.first()->departureDateTime().date()); journey->setDepartureTime(depTime); @@ -523,7 +523,7 @@ QList ParserResRobot::parseJourneySegments(const QVari foreach (QVariant segmentData, segments) { QVariantMap segment = segmentData.toMap(); - JourneyDetailResultItem* resultItem = new JourneyDetailResultItem(results); + JourneyDetailResultItem* resultItem = new JourneyDetailResultItem;//FIXME will leak in QML // Departure QVariantMap departure = segment.value("departure").toMap(); From d04434e6d89a0b01f561c09dae97662354446a34 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Thu, 28 May 2015 02:12:07 +0200 Subject: [PATCH 04/85] added missing destructors --- src/parser/parser_definitions.cpp | 20 ++++++++++++++++++++ src/parser/parser_definitions.h | 4 ++++ 2 files changed, 24 insertions(+) diff --git a/src/parser/parser_definitions.cpp b/src/parser/parser_definitions.cpp index 970fcce5..8976bf51 100644 --- a/src/parser/parser_definitions.cpp +++ b/src/parser/parser_definitions.cpp @@ -71,6 +71,16 @@ TimetableEntry::TimetableEntry() //------------- JourneyResultList +JourneyResultList::JourneyResultList(QObject * parent) : QObject(parent) +{ + +} + +JourneyResultList::~JourneyResultList() +{ + qDeleteAll(m_items); +} + qreal JourneyResultList::itemcount() { return m_items.count(); @@ -234,6 +244,16 @@ void JourneyResultItem::setInternalData2(const QString &internalData2) //------------- JourneyDetailResultList +JourneyDetailResultList::JourneyDetailResultList(QObject * parent) : QObject(parent) +{ + +} + +JourneyDetailResultList::~JourneyDetailResultList() +{ + qDeleteAll(m_items); +} + QString JourneyDetailResultList::id() const { return m_id; diff --git a/src/parser/parser_definitions.h b/src/parser/parser_definitions.h index 94278a1e..e15d1620 100644 --- a/src/parser/parser_definitions.h +++ b/src/parser/parser_definitions.h @@ -141,6 +141,8 @@ class JourneyResultList : public QObject public slots: JourneyResultItem *getItem(int); public: + explicit JourneyResultList(QObject * parent = 0); + virtual ~JourneyResultList(); void appendItem(JourneyResultItem *item); qreal itemcount(); QString departureStation() const; @@ -230,6 +232,8 @@ class JourneyDetailResultList : public QObject public slots: JourneyDetailResultItem *getItem(int); public: + explicit JourneyDetailResultList(QObject * parent = 0); + virtual ~JourneyDetailResultList(); void appendItem(JourneyDetailResultItem *item); qreal itemcount(); QString id() const; From 43dd9631cb90c8abc2493a1a4dfbeb6b0721e95e Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Thu, 28 May 2015 02:13:38 +0200 Subject: [PATCH 05/85] fixing leaks --- src/parser/parser_hafasbinary.cpp | 9 +++++---- src/parser/parser_hafasxml.cpp | 24 ++++++++++++++++++++++-- src/parser/parser_hafasxml.h | 2 ++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/parser/parser_hafasbinary.cpp b/src/parser/parser_hafasbinary.cpp index 7fafab07..a6105885 100644 --- a/src/parser/parser_hafasbinary.cpp +++ b/src/parser/parser_hafasbinary.cpp @@ -43,7 +43,8 @@ void ParserHafasBinary::searchJourney(const Station &departureStation, const Sta currentRequestState = FahrplanNS::searchJourneyRequest; hafasContext.seqNr = ""; - lastJourneyResultList = NULL; + + cleanupJourney(); QString trainrestr = getTrainRestrictionsCodes(trainrestrictions); @@ -85,8 +86,8 @@ void ParserHafasBinary::searchJourney(const Station &departureStation, const Sta void ParserHafasBinary::parseSearchJourney(QNetworkReply *networkReply) { - lastJourneyResultList = new JourneyResultList(); - journeyDetailInlineData.clear(); + lastJourneyResultList = new JourneyResultList(this); + stringCache.clear(); QByteArray tmpBuffer = networkReply->readAll(); @@ -324,7 +325,7 @@ void ParserHafasBinary::parseSearchJourney(QNetworkReply *networkReply) qDebug()<<"conId"<readAll())) diff --git a/src/parser/parser_hafasxml.h b/src/parser/parser_hafasxml.h index aee85971..6ad4a46e 100644 --- a/src/parser/parser_hafasxml.h +++ b/src/parser/parser_hafasxml.h @@ -57,6 +57,7 @@ class ParserHafasXml : public ParserAbstract Q_OBJECT public: explicit ParserHafasXml(QObject *parent = 0); + virtual ~ParserHafasXml(); static QString getName() { return "HafasXML"; } virtual QString name() { return getName(); } virtual QString shortName() { return getName(); } @@ -90,6 +91,7 @@ public slots: void parseSearchLaterJourney(QNetworkReply *networkReply); void parseSearchEarlierJourney(QNetworkReply *networkReply); void parseJourneyDetails(QNetworkReply *networkReply); + void cleanupJourney(); virtual QString getTrainRestrictionsCodes(int trainrestrictions); JourneyResultList *lastJourneyResultList; From 2b46f13af433e6cbc1bf765f1f2fb4f190f380ba Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Thu, 28 May 2015 02:15:47 +0200 Subject: [PATCH 06/85] ownership, concurrency and and destructor for parser backend manager and thread --- src/fahrplan_backend_manager.cpp | 10 +++++++++- src/fahrplan_backend_manager.h | 1 + src/fahrplan_parser_thread.h | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/fahrplan_backend_manager.cpp b/src/fahrplan_backend_manager.cpp index 732357bb..aed57f55 100644 --- a/src/fahrplan_backend_manager.cpp +++ b/src/fahrplan_backend_manager.cpp @@ -26,6 +26,14 @@ FahrplanBackendManager::FahrplanBackendManager(int defaultParser, QObject *paren currentParserIndex = defaultParser; } +FahrplanBackendManager::~FahrplanBackendManager() +{ + if (m_parser) { + // Parser object will be autodeleted after the thread quits. + m_parser->quit(); + } +} + QStringList FahrplanBackendManager::getParserList() { QStringList result; @@ -68,7 +76,7 @@ void FahrplanBackendManager::setParser(int index) m_parser->quit(); } - m_parser = new FahrplanParserThread(); + m_parser = new FahrplanParserThread(this); m_parser->init(index); emit parserChanged(m_parser->name(), currentParserIndex); diff --git a/src/fahrplan_backend_manager.h b/src/fahrplan_backend_manager.h index fc7797b9..1672cc8f 100644 --- a/src/fahrplan_backend_manager.h +++ b/src/fahrplan_backend_manager.h @@ -28,6 +28,7 @@ class FahrplanBackendManager : public QObject public: explicit FahrplanBackendManager(int defaultParser, QObject *parent = 0); + virtual ~FahrplanBackendManager(); QStringList getParserList(); void setParser(int index); FahrplanParserThread *getParser(); diff --git a/src/fahrplan_parser_thread.h b/src/fahrplan_parser_thread.h index 8072f1ee..90a3d758 100644 --- a/src/fahrplan_parser_thread.h +++ b/src/fahrplan_parser_thread.h @@ -89,7 +89,7 @@ public slots: void run(); private: - bool m_ready; + volatile bool m_ready; int i_parser; QStringList m_trainrestrictions; From 7b975141e1242fe8c7ece1eb63383aca05fe78a9 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Sun, 31 May 2015 23:27:52 +0200 Subject: [PATCH 07/85] clearJourney() is a more proper name --- src/parser/parser_hafasbinary.cpp | 2 +- src/parser/parser_hafasxml.cpp | 6 +++--- src/parser/parser_hafasxml.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/parser/parser_hafasbinary.cpp b/src/parser/parser_hafasbinary.cpp index a6105885..5c57dd78 100644 --- a/src/parser/parser_hafasbinary.cpp +++ b/src/parser/parser_hafasbinary.cpp @@ -44,7 +44,7 @@ void ParserHafasBinary::searchJourney(const Station &departureStation, const Sta currentRequestState = FahrplanNS::searchJourneyRequest; hafasContext.seqNr = ""; - cleanupJourney(); + clearJourney(); QString trainrestr = getTrainRestrictionsCodes(trainrestrictions); diff --git a/src/parser/parser_hafasxml.cpp b/src/parser/parser_hafasxml.cpp index f89f7c85..ec0ec1cf 100644 --- a/src/parser/parser_hafasxml.cpp +++ b/src/parser/parser_hafasxml.cpp @@ -54,10 +54,10 @@ ParserHafasXml::ParserHafasXml(QObject *parent) : ParserHafasXml::~ParserHafasXml() { - cleanupJourney(); + clearJourney(); } -void ParserHafasXml::cleanupJourney() +void ParserHafasXml::clearJourney() { if (lastJourneyResultList) { delete lastJourneyResultList; @@ -539,7 +539,7 @@ void ParserHafasXml::searchJourney(const Station &departureStation, const Statio currentRequestState = FahrplanNS::searchJourneyRequest; hafasContext.seqNr = ""; - cleanupJourney(); + clearJourney(); QString trainrestr = getTrainRestrictionsCodes(trainrestrictions); diff --git a/src/parser/parser_hafasxml.h b/src/parser/parser_hafasxml.h index 6ad4a46e..513d206a 100644 --- a/src/parser/parser_hafasxml.h +++ b/src/parser/parser_hafasxml.h @@ -75,6 +75,7 @@ public slots: bool supportsTimeTable(); bool supportsTimeTableDirection(); QStringList getTrainRestrictions(); + virtual void clearJourney(); protected: QString baseXmlUrl; @@ -91,7 +92,6 @@ public slots: void parseSearchLaterJourney(QNetworkReply *networkReply); void parseSearchEarlierJourney(QNetworkReply *networkReply); void parseJourneyDetails(QNetworkReply *networkReply); - void cleanupJourney(); virtual QString getTrainRestrictionsCodes(int trainrestrictions); JourneyResultList *lastJourneyResultList; From 3b16f286a9eb43135870f58d85260befda6730c2 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Sun, 31 May 2015 23:29:41 +0200 Subject: [PATCH 08/85] adding clearJourney to EFA parser --- src/parser/parser_efa.cpp | 15 +++++++++++++++ src/parser/parser_efa.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/src/parser/parser_efa.cpp b/src/parser/parser_efa.cpp index 0ed6c2b5..3fe3a3a4 100755 --- a/src/parser/parser_efa.cpp +++ b/src/parser/parser_efa.cpp @@ -108,6 +108,19 @@ ParserEFA::ParserEFA(QObject *parent) : m_timeTableForStationParameters.isValid = false; } +ParserEFA::~ParserEFA() +{ + clearJourney(); +} + +void ParserEFA::clearJourney() +{ + if (lastJourneyResultList) { + delete lastJourneyResultList; + lastJourneyResultList = NULL; + } +} + bool ParserEFA::supportsGps() { return true; @@ -504,6 +517,8 @@ void ParserEFA::searchJourney(const Station &departureStation, const Station &vi void ParserEFA::parseSearchJourney(QNetworkReply *networkReply) { qDebug() << "ParserEFA::parseSearchJourney(QNetworkReply *networkReply)"; + clearJourney(); + lastJourneyResultList = new JourneyResultList(); for (QHash::Iterator it = cachedJourneyDetailsEfa.begin(); it != cachedJourneyDetailsEfa.end();) { diff --git a/src/parser/parser_efa.h b/src/parser/parser_efa.h index 1ce9573b..c31e3cfc 100755 --- a/src/parser/parser_efa.h +++ b/src/parser/parser_efa.h @@ -29,6 +29,7 @@ class ParserEFA : public ParserAbstract Q_OBJECT public: explicit ParserEFA(QObject *parent = 0); + virtual ~ParserEFA(); static QString getName() { return "EFA"; } virtual QString name() { return getName(); } virtual QString shortName() { return getName(); } @@ -47,6 +48,7 @@ public slots: bool supportsTimeTableDirection(); void checkForError(QDomDocument *serverReplyDomDoc); QStringList getTrainRestrictions(); + virtual void clearJourney(); protected: QString baseRestUrl; From 32243d82f91349de2514e509a3ef5a806431b999 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 1 Jun 2015 00:05:17 +0200 Subject: [PATCH 09/85] fixing ParserXmlVasttrafikSe memory leaks --- src/parser/parser_xmlvasttrafikse.cpp | 69 ++++++++++++++++----------- src/parser/parser_xmlvasttrafikse.h | 4 ++ 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/src/parser/parser_xmlvasttrafikse.cpp b/src/parser/parser_xmlvasttrafikse.cpp index f702413c..b99e7d58 100644 --- a/src/parser/parser_xmlvasttrafikse.cpp +++ b/src/parser/parser_xmlvasttrafikse.cpp @@ -46,6 +46,18 @@ ParserXmlVasttrafikSe::ParserXmlVasttrafikSe(QObject *parent) m_timeTableForStationParameters.isValid = false; } +ParserXmlVasttrafikSe::~ParserXmlVasttrafikSe() +{ + clearJourney(); +} + +void ParserXmlVasttrafikSe::clearJourney() +{ + if (lastJourneyResultList) { + delete lastJourneyResultList; + lastJourneyResultList = NULL; + } +} void ParserXmlVasttrafikSe::getTimeTableForStation(const Station ¤tStation, const Station &, const QDateTime &dateTime, Mode mode, int) { @@ -305,7 +317,8 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) { qDebug() << "ParserXmlVasttrafikSe::parseSearchJourney(networkReply.url()=" << networkReply->url().toString() << ")"; - JourneyResultList *journeyResultList = new JourneyResultList(); + clearJourney(); + lastJourneyResultList = new JourneyResultList(this); for (QHash::Iterator it = cachedJourneyDetails.begin(); it != cachedJourneyDetails.end();) { JourneyDetailResultList *jdrl = it.value(); @@ -314,11 +327,11 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) } /// Use fallback values for empty results (i.e. no connections found) - journeyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); - journeyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); - journeyResultList->setArrivalStation(m_searchJourneyParameters.arrivalStation.name); + lastJourneyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); + lastJourneyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); + lastJourneyResultList->setArrivalStation(m_searchJourneyParameters.arrivalStation.name); //: DATE, TIME - journeyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(m_searchJourneyParameters.dateTime.date().toString(Qt::DefaultLocaleShortDate)).arg(m_searchJourneyParameters.dateTime.time().toString(Qt::DefaultLocaleShortDate))); + lastJourneyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(m_searchJourneyParameters.dateTime.date().toString(Qt::DefaultLocaleShortDate)).arg(m_searchJourneyParameters.dateTime.time().toString(Qt::DefaultLocaleShortDate))); m_earliestArrival = m_latestResultDeparture = QDateTime(); @@ -329,8 +342,8 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) if (doc.setContent(xmlRawtext, false)) { QDomNodeList tripNodeList = doc.elementsByTagName("Trip"); for (unsigned int i = 0; i < tripNodeList.length(); ++i) { - JourneyResultItem *jritem = new JourneyResultItem(journeyResultList); - JourneyDetailResultList *detailsList = new JourneyDetailResultList(); + JourneyResultItem *jritem = new JourneyResultItem(lastJourneyResultList); + JourneyDetailResultList *detailsList = new JourneyDetailResultList(this); /// Set default values for journey's start and end time QDateTime journeyStart = QDateTime::currentDateTime(); @@ -351,15 +364,15 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) journeyStart.setTime(time); if (i == 0) { const QDate date = QDate::fromString(getAttribute(originNode, "date"), QLatin1String("yyyy-MM-dd")); - journeyResultList->setDepartureStation(getAttribute(originNode, "name")); + lastJourneyResultList->setDepartureStation(getAttribute(originNode, "name")); //: DATE, TIME - journeyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(date.toString(Qt::DefaultLocaleShortDate)).arg(time.toString(Qt::DefaultLocaleShortDate))); + lastJourneyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(date.toString(Qt::DefaultLocaleShortDate)).arg(time.toString(Qt::DefaultLocaleShortDate))); } } if (j == legNodeList.length() - 1) { journeyEnd.setTime(QTime::fromString(getAttribute(destinationNode, "time"), "hh:mm")); if (i == 0) - journeyResultList->setArrivalStation(getAttribute(destinationNode, "name")); + lastJourneyResultList->setArrivalStation(getAttribute(destinationNode, "name")); } if (getAttribute(legNode, "type") != QLatin1String("WALK") || getAttribute(originNode, "name") != getAttribute(destinationNode, "name")) { @@ -441,14 +454,14 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) else if (tripRtStatus == TRIP_RTDATA_ONTIME) jritem->setMiscInfo(tr("on time")); - journeyResultList->appendItem(jritem); + lastJourneyResultList->appendItem(jritem); const QString id = QString::number(i); jritem->setId(id); detailsList->setId(id); - detailsList->setDepartureStation(journeyResultList->departureStation()); - detailsList->setViaStation(journeyResultList->viaStation()); - detailsList->setArrivalStation(journeyResultList->arrivalStation()); + detailsList->setDepartureStation(lastJourneyResultList->departureStation()); + detailsList->setViaStation(lastJourneyResultList->viaStation()); + detailsList->setArrivalStation(lastJourneyResultList->arrivalStation()); detailsList->setDuration(jritem->duration()); detailsList->setArrivalDateTime(journeyEnd); detailsList->setDepartureDateTime(journeyStart); @@ -461,7 +474,7 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) } } - emit journeyResult(journeyResultList); + emit journeyResult(lastJourneyResultList); } void ParserXmlVasttrafikSe::searchJourneyLater() @@ -469,13 +482,14 @@ void ParserXmlVasttrafikSe::searchJourneyLater() if (m_latestResultDeparture.isValid()) searchJourney(m_searchJourneyParameters.departureStation, m_searchJourneyParameters.arrivalStation, m_searchJourneyParameters.viaStation, m_latestResultDeparture, Departure, 0); else { - JourneyResultList *journeyResultList = new JourneyResultList(); - journeyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); - journeyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); - journeyResultList->setArrivalStation(m_searchJourneyParameters.arrivalStation.name); + clearJourney(); + lastJourneyResultList = new JourneyResultList(); + lastJourneyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); + lastJourneyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); + lastJourneyResultList->setArrivalStation(m_searchJourneyParameters.arrivalStation.name); //: DATE, TIME - journeyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(m_searchJourneyParameters.dateTime.date().toString(Qt::DefaultLocaleShortDate)).arg(m_searchJourneyParameters.dateTime.time().toString(Qt::DefaultLocaleShortDate))); - emit journeyResult(journeyResultList); + lastJourneyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(m_searchJourneyParameters.dateTime.date().toString(Qt::DefaultLocaleShortDate)).arg(m_searchJourneyParameters.dateTime.time().toString(Qt::DefaultLocaleShortDate))); + emit journeyResult(lastJourneyResultList); } } @@ -484,13 +498,14 @@ void ParserXmlVasttrafikSe::searchJourneyEarlier() if (m_earliestArrival.isValid()) searchJourney(m_searchJourneyParameters.departureStation, m_searchJourneyParameters.arrivalStation, m_searchJourneyParameters.viaStation, m_earliestArrival, Arrival, 0); else { - JourneyResultList *journeyResultList = new JourneyResultList(); - journeyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); - journeyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); - journeyResultList->setArrivalStation(m_searchJourneyParameters.arrivalStation.name); + clearJourney(); + lastJourneyResultList = new JourneyResultList(); + lastJourneyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); + lastJourneyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); + lastJourneyResultList->setArrivalStation(m_searchJourneyParameters.arrivalStation.name); //: DATE, TIME - journeyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(m_searchJourneyParameters.dateTime.date().toString(Qt::DefaultLocaleShortDate)).arg(m_searchJourneyParameters.dateTime.time().toString(Qt::DefaultLocaleShortDate))); - emit journeyResult(journeyResultList); + lastJourneyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(m_searchJourneyParameters.dateTime.date().toString(Qt::DefaultLocaleShortDate)).arg(m_searchJourneyParameters.dateTime.time().toString(Qt::DefaultLocaleShortDate))); + emit journeyResult(lastJourneyResultList); } } diff --git a/src/parser/parser_xmlvasttrafikse.h b/src/parser/parser_xmlvasttrafikse.h index c75004eb..238b6435 100644 --- a/src/parser/parser_xmlvasttrafikse.h +++ b/src/parser/parser_xmlvasttrafikse.h @@ -28,6 +28,7 @@ class ParserXmlVasttrafikSe : public ParserAbstract public: explicit ParserXmlVasttrafikSe(QObject *parent = 0); + virtual ~ParserXmlVasttrafikSe(); static QString getName() { return QString("%1 (vasttrafik.se)").arg(tr("Sweden")); } virtual QString name() { return getName(); } virtual QString shortName() { return "vasttrafik.se"; } @@ -46,6 +47,7 @@ public slots: virtual bool supportsTimeTableDirection(); // virtual QStringList getTrainRestrictions(); // void cancelRequest(); + virtual void clearJourney(); protected: virtual void parseStationsByName(QNetworkReply *networkReply); @@ -53,6 +55,8 @@ public slots: virtual void parseTimeTable(QNetworkReply *networkReply); virtual void parseSearchJourney(QNetworkReply *networkReply); + JourneyResultList *lastJourneyResultList; + private: static const qlonglong TRIP_RTDATA_NONE; static const qlonglong TRIP_RTDATA_ONTIME; From cf3ad032196654ba003688d9f6d8a1fd155ac000 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 1 Jun 2015 00:28:42 +0200 Subject: [PATCH 10/85] one more small fix to vasttrafikse --- src/parser/parser_xmlvasttrafikse.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/parser/parser_xmlvasttrafikse.cpp b/src/parser/parser_xmlvasttrafikse.cpp index b99e7d58..02e682b1 100644 --- a/src/parser/parser_xmlvasttrafikse.cpp +++ b/src/parser/parser_xmlvasttrafikse.cpp @@ -57,6 +57,12 @@ void ParserXmlVasttrafikSe::clearJourney() delete lastJourneyResultList; lastJourneyResultList = NULL; } + + for (QHash::Iterator it = cachedJourneyDetails.begin(); it != cachedJourneyDetails.end();) { + JourneyDetailResultList *jdrl = it.value(); + it = cachedJourneyDetails.erase(it); + delete jdrl; + } } void ParserXmlVasttrafikSe::getTimeTableForStation(const Station ¤tStation, const Station &, const QDateTime &dateTime, Mode mode, int) @@ -320,12 +326,6 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) clearJourney(); lastJourneyResultList = new JourneyResultList(this); - for (QHash::Iterator it = cachedJourneyDetails.begin(); it != cachedJourneyDetails.end();) { - JourneyDetailResultList *jdrl = it.value(); - it = cachedJourneyDetails.erase(it); - delete jdrl; - } - /// Use fallback values for empty results (i.e. no connections found) lastJourneyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); lastJourneyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); From 486eb79fe2c41f89e9f642e4f3b551b2760ca6d9 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 1 Jun 2015 00:29:10 +0200 Subject: [PATCH 11/85] fixing ninetwo memory leaks --- src/parser/parser_ninetwo.cpp | 39 +++++++++++++++++++++++++++-------- src/parser/parser_ninetwo.h | 4 ++++ 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/parser/parser_ninetwo.cpp b/src/parser/parser_ninetwo.cpp index 4dd83937..95d88b2f 100644 --- a/src/parser/parser_ninetwo.cpp +++ b/src/parser/parser_ninetwo.cpp @@ -54,6 +54,25 @@ ParserNinetwo::ParserNinetwo(QObject *parent):ParserAbstract(parent) lastCoordinates.isValid = false; } +ParserNinetwo::~ParserNinetwo() +{ + clearJourney(); +} + +void ParserNinetwo::clearJourney() +{ + if (lastJourneyResultList) { + delete lastJourneyResultList; + lastJourneyResultList = NULL; + } + + for (QMap::Iterator it = cachedResults.begin(); it != cachedResults.end();) { + JourneyDetailResultList *jdrl = it.value(); + it = cachedResults.erase(it); + delete jdrl; + } +} + void ParserNinetwo::getTimeTableForStation(const Station ¤tStation, const Station &, const QDateTime &, @@ -336,7 +355,9 @@ void ParserNinetwo::parseSearchJourney(QNetworkReply *networkReply) QVariantList journeys = doc.value("journeys").toList(); - JourneyResultList* result=new JourneyResultList; + clearJourney(); + + lastJourneyResultList = new JourneyResultList(this); QDateTime arrival; QDateTime departure; @@ -345,7 +366,7 @@ void ParserNinetwo::parseSearchJourney(QNetworkReply *networkReply) for (i = journeys.constBegin(); i != journeys.constEnd(); ++i) { QVariantMap journey = i->toMap(); parseJourneyOption(journey); - JourneyResultItem* item = new JourneyResultItem(result); + JourneyResultItem* item = new JourneyResultItem(lastJourneyResultList); arrival = QDateTime::fromString(journey.value("arrival").toString(), "yyyy-MM-ddTHH:mm"); departure = QDateTime::fromString(journey.value("departure").toString(), "yyyy-MM-ddTHH:mm"); @@ -376,17 +397,17 @@ void ParserNinetwo::parseSearchJourney(QNetworkReply *networkReply) int minutes = departure.secsTo(arrival)/60; item->setDuration(QString("%1:%2").arg(minutes/60).arg(minutes%60,2,10,QChar('0'))); item->setId(journey.value("id").toString()); - result->appendItem(item); + lastJourneyResultList ->appendItem(item); //Set result metadata based on first result - if (result->itemcount() == 1) { - result->setTimeInfo(arrival.date().toString()); - result->setDepartureStation(cachedResults[item->id()]->departureStation()); - result->setArrivalStation(cachedResults[item->id()]->arrivalStation()); + if (lastJourneyResultList ->itemcount() == 1) { + lastJourneyResultList ->setTimeInfo(arrival.date().toString()); + lastJourneyResultList ->setDepartureStation(cachedResults[item->id()]->departureStation()); + lastJourneyResultList ->setArrivalStation(cachedResults[item->id()]->arrivalStation()); } } lastsearch.lastOption=departure; - emit journeyResult(result); + emit journeyResult(lastJourneyResultList ); } void ParserNinetwo::parseSearchLaterJourney(QNetworkReply *) @@ -406,7 +427,7 @@ void ParserNinetwo::parseJourneyDetails(QNetworkReply *) void ParserNinetwo::parseJourneyOption(const QVariantMap &object) { - JourneyDetailResultList* result = new JourneyDetailResultList; + JourneyDetailResultList* result = new JourneyDetailResultList(this); QString id = object.value("id").toString(); QVariantList legs = object.value("legs").toList(); diff --git a/src/parser/parser_ninetwo.h b/src/parser/parser_ninetwo.h index a58c95e9..e142004f 100644 --- a/src/parser/parser_ninetwo.h +++ b/src/parser/parser_ninetwo.h @@ -60,6 +60,7 @@ class ParserNinetwo : public ParserAbstract public: ParserNinetwo(QObject* parent = 0); + virtual ~ParserNinetwo(); // ParserAbstract interface public: @@ -80,6 +81,7 @@ public slots: bool supportsTimeTable() { return true; } bool supportsTimeTableDirection() { return false; } QStringList getTrainRestrictions(); + virtual void clearJourney(); protected: void parseTimeTable(QNetworkReply *networkReply); @@ -91,6 +93,8 @@ public slots: void parseJourneyDetails(QNetworkReply *networkReply); QMap cachedResults; + JourneyResultList *lastJourneyResultList; + private: void parseJourneyOption(const QVariantMap &object); }; From 52a8675094ea3a04a0bd4efd23d799c582e39088 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 1 Jun 2015 00:29:31 +0200 Subject: [PATCH 12/85] fixing resrobot memory leaks --- src/parser/parser_resrobot.cpp | 30 ++++++++++++++++++++++-------- src/parser/parser_resrobot.h | 4 ++++ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/parser/parser_resrobot.cpp b/src/parser/parser_resrobot.cpp index f2b1b1ab..d097fbb5 100644 --- a/src/parser/parser_resrobot.cpp +++ b/src/parser/parser_resrobot.cpp @@ -87,6 +87,19 @@ ParserResRobot::ParserResRobot(QObject *parent) : transportModeStrings[QString::fromUtf8("Γ–vriga tΓ₯g")] = tr("Other train"); } +ParserResRobot::~ParserResRobot() +{ + clearJourney(); +} + +void ParserResRobot::clearJourney() +{ + if (lastJourneyResultList) { + delete lastJourneyResultList; + lastJourneyResultList = NULL; + } +} + bool ParserResRobot::supportsGps() { return true; @@ -430,7 +443,8 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) cachedResults.clear(); - JourneyResultList *journeyList = new JourneyResultList(); + clearJourney(); + lastJourneyResultList = new JourneyResultList(this); int journeyCounter = 0; foreach (QVariant journeyData, journeyListData) { @@ -454,7 +468,7 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) if (transportModes.count() == 0 && segments.count() == 1) transportModes.append(segments.first()->train()); - JourneyDetailResultList* journeyDetails = new JourneyDetailResultList; + JourneyDetailResultList* journeyDetails = new JourneyDetailResultList(this); foreach (JourneyDetailResultItem* segment, segments) journeyDetails->appendItem(segment); journeyDetails->setId(journeyID); @@ -479,7 +493,7 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) else if (arrDayDiff < 0) arrTime += QString::number(arrDayDiff); - JourneyResultItem* journey = new JourneyResultItem(journeyList); + JourneyResultItem* journey = new JourneyResultItem(lastJourneyResultList); journey->setId(journeyID); journey->setDate(segments.first()->departureDateTime().date()); journey->setDepartureTime(depTime); @@ -487,7 +501,7 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) journey->setTrainType(transportModes.join(", ")); journey->setDuration(duration); journey->setTransfers(QString::number(transportModes.count()-1)); - journeyList->appendItem(journey); + lastJourneyResultList->appendItem(journey); if (journeyCounter == 0) { if (lastJourneySearch.mode == Departure) @@ -502,16 +516,16 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) ++journeyCounter; } - journeyList->setDepartureStation(lastJourneySearch.from.name); - journeyList->setArrivalStation(lastJourneySearch.to.name); + lastJourneyResultList->setDepartureStation(lastJourneySearch.from.name); + lastJourneyResultList->setArrivalStation(lastJourneySearch.to.name); QString modeString; if (lastJourneySearch.mode == Arrival) modeString = tr("Arrivals"); else modeString = tr("Departures"); - journeyList->setTimeInfo(modeString + " " + lastJourneySearch.dateTime.toString(tr("ddd MMM d, HH:mm"))); + lastJourneyResultList->setTimeInfo(modeString + " " + lastJourneySearch.dateTime.toString(tr("ddd MMM d, HH:mm"))); - emit journeyResult(journeyList); + emit journeyResult(lastJourneyResultList); } // Parse info about one journey option. Store detailed info about segments for later use. diff --git a/src/parser/parser_resrobot.h b/src/parser/parser_resrobot.h index 3ddef51a..9d17664b 100644 --- a/src/parser/parser_resrobot.h +++ b/src/parser/parser_resrobot.h @@ -60,6 +60,7 @@ class ParserResRobot : public ParserAbstract Q_OBJECT public: explicit ParserResRobot(QObject *parent = 0); + virtual ~ParserResRobot(); static QString getName() { return QString("%1 (resrobot.se)").arg(tr("Sweden")); } virtual QString name() { return getName(); } @@ -84,6 +85,7 @@ public slots: virtual void searchJourneyLater(); virtual void searchJourneyEarlier(); virtual void getJourneyDetails(const QString &id); + virtual void clearJourney(); protected: virtual void parseTimeTable(QNetworkReply *networkReply); @@ -94,6 +96,8 @@ public slots: virtual void parseSearchEarlierJourney(QNetworkReply *networkReply); virtual void parseJourneyDetails(QNetworkReply *networkReply); + JourneyResultList *lastJourneyResultList; + private: enum transportModePreset { ALL_TRANSPORT_MODES, From 8741cfaa0fb27c68c214f2eb489211852207921c Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 1 Jun 2015 00:33:23 +0200 Subject: [PATCH 13/85] providing clearJourney at the top level --- src/parser/parser_abstract.cpp | 8 +++++++- src/parser/parser_abstract.h | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/parser/parser_abstract.cpp b/src/parser/parser_abstract.cpp index 86ade9e1..a9c99bd9 100644 --- a/src/parser/parser_abstract.cpp +++ b/src/parser/parser_abstract.cpp @@ -43,7 +43,7 @@ ParserAbstract::ParserAbstract(QObject *parent) : currentRequestState = FahrplanNS::noneRequest; - requestTimeout = new QTimer(); + requestTimeout = new QTimer(this); connect(requestTimeout, SIGNAL(timeout()), this, SLOT(networkReplyTimedOut())); @@ -52,10 +52,16 @@ ParserAbstract::ParserAbstract(QObject *parent) : ParserAbstract::~ParserAbstract() { + clearJourney(); delete requestTimeout; delete NetworkManager; } +void ParserAbstract::clearJourney() +{ + +} + void ParserAbstract::networkReplyFinished(QNetworkReply *networkReply) { FahrplanNS::curReqStates internalRequestState = currentRequestState; diff --git a/src/parser/parser_abstract.h b/src/parser/parser_abstract.h index 969799ad..af236afd 100644 --- a/src/parser/parser_abstract.h +++ b/src/parser/parser_abstract.h @@ -37,7 +37,7 @@ class ParserAbstract : public QObject enum Mode { Departure = 0, Arrival = 1 }; explicit ParserAbstract(QObject *parent = 0); - ~ParserAbstract(); + virtual ~ParserAbstract(); static QString getName() { return "Abstract"; } virtual QString name() { return getName(); } @@ -58,6 +58,7 @@ public slots: virtual bool supportsTimeTableDirection(); virtual QStringList getTrainRestrictions(); void cancelRequest(); + virtual void clearJourney(); signals: void stationsResult(const StationsList &result); From 12260d3956d0d3a875fc86864b8d6bb4e3a85906 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Thu, 21 May 2015 01:09:17 +0200 Subject: [PATCH 14/85] Fix for QObject* ownership bugs Due to returning QObject* in calls to C++ objects from QML (e.g. getItem(i)), those objects were changing ownership to QML and were subject to gc. That could've been noticed during switching between journey results and journey details results (instantly switch back and forth to create enough garbage). `var item = result.getItem(i);` `item` would be null after some time. So it was ending up in page showing loader and not doing anything or in a bit more rare cases with segfault. --- rpm/harbour-fahrplan2.yaml | 2 ++ src/parser/parser_definitions.cpp | 9 +++++++++ src/parser/parser_definitions.h | 2 ++ src/parser/parser_efa.cpp | 4 ++-- src/parser/parser_hafasbinary.cpp | 4 ++-- src/parser/parser_hafasxml.cpp | 4 ++-- src/parser/parser_xmlvasttrafikse.cpp | 4 ++-- 7 files changed, 21 insertions(+), 8 deletions(-) diff --git a/rpm/harbour-fahrplan2.yaml b/rpm/harbour-fahrplan2.yaml index fc5836da..d0c023b1 100644 --- a/rpm/harbour-fahrplan2.yaml +++ b/rpm/harbour-fahrplan2.yaml @@ -15,8 +15,10 @@ PkgConfigBR: - Qt5Quick - Qt5Qml - Qt5Core +- sailfishapp Requires: - sailfishsilica-qt5 >= 0.10.9 +- qt5-qtdeclarative-import-positioning Files: - '%{_datadir}/icons/hicolor/86x86/apps/%{name}.png' - '%{_datadir}/applications/%{name}.desktop' diff --git a/src/parser/parser_definitions.cpp b/src/parser/parser_definitions.cpp index 13363e72..970fcce5 100644 --- a/src/parser/parser_definitions.cpp +++ b/src/parser/parser_definitions.cpp @@ -127,6 +127,10 @@ void JourneyResultList::setTimeInfo(const QString &timeInfo) } //------------- JourneyResultItem +JourneyResultItem::JourneyResultItem(QObject *parent) : QObject(parent) +{ + +} QString JourneyResultItem::id() const { @@ -327,6 +331,11 @@ void JourneyDetailResultList::setDuration(const QString &duration) //------------- JourneyDetailResultItem +JourneyDetailResultItem::JourneyDetailResultItem(QObject *parent) : QObject(parent) +{ + +} + QString JourneyDetailResultItem::departureStation() const { return m_departureStation; diff --git a/src/parser/parser_definitions.h b/src/parser/parser_definitions.h index 7587c1ab..94278a1e 100644 --- a/src/parser/parser_definitions.h +++ b/src/parser/parser_definitions.h @@ -95,6 +95,7 @@ class JourneyResultItem : public QObject Q_PROPERTY(QString internalData2 READ internalData2 WRITE setInternalData2) public: + explicit JourneyResultItem(QObject * parent = 0); QString id() const; void setId(const QString &); QDate date() const; @@ -176,6 +177,7 @@ class JourneyDetailResultItem : public QObject Q_PROPERTY(QString internalData1 READ internalData1 WRITE setInternalData1) Q_PROPERTY(QString internalData2 READ internalData2 WRITE setInternalData2) public: + explicit JourneyDetailResultItem(QObject * parent = 0); QString departureStation() const; void setDepartureStation(const QString &); QString departureInfo() const; diff --git a/src/parser/parser_efa.cpp b/src/parser/parser_efa.cpp index d934be35..0ed6c2b5 100755 --- a/src/parser/parser_efa.cpp +++ b/src/parser/parser_efa.cpp @@ -542,7 +542,7 @@ void ParserEFA::parseSearchJourney(QNetworkReply *networkReply) info = tr("Guaranteed connection"); } motNameList.append(motName); - JourneyDetailResultItem *jdrItem = new JourneyDetailResultItem(); + JourneyDetailResultItem *jdrItem = new JourneyDetailResultItem(detailsList); jdrItem->setTrain(motName); jdrItem->setInfo(info); jdrItem->setDirection(motElement.attribute("destination")); @@ -580,7 +580,7 @@ void ParserEFA::parseSearchJourney(QNetworkReply *networkReply) detailsList->setDepartureDateTime(departureDateTime); cachedJourneyDetailsEfa[id] = detailsList; - JourneyResultItem *item = new JourneyResultItem(); + JourneyResultItem *item = new JourneyResultItem(lastJourneyResultList); item->setDate(departureDateTime.date()); item->setId(id); item->setTransfers(changes); diff --git a/src/parser/parser_hafasbinary.cpp b/src/parser/parser_hafasbinary.cpp index 8568a175..7fafab07 100644 --- a/src/parser/parser_hafasbinary.cpp +++ b/src/parser/parser_hafasbinary.cpp @@ -328,7 +328,7 @@ void ParserHafasBinary::parseSearchJourney(QNetworkReply *networkReply) for (int iPart = 0; iPart < numParts; iPart++) { - JourneyDetailResultItem *inlineItem = new JourneyDetailResultItem(); + JourneyDetailResultItem *inlineItem = new JourneyDetailResultItem(inlineResults); hafasData.device()->seek(0x4a + partsOffset + iPart * 20); @@ -571,7 +571,7 @@ void ParserHafasBinary::parseSearchJourney(QNetworkReply *networkReply) lineNames.removeDuplicates(); - JourneyResultItem *item = new JourneyResultItem(); + JourneyResultItem *item = new JourneyResultItem(lastJourneyResultList); item->setDate(journeyDate); item->setId(connectionId); item->setTransfers(QString::number(numChanges)); diff --git a/src/parser/parser_hafasxml.cpp b/src/parser/parser_hafasxml.cpp index ee129b3c..b110c62b 100644 --- a/src/parser/parser_hafasxml.cpp +++ b/src/parser/parser_hafasxml.cpp @@ -656,7 +656,7 @@ void ParserHafasXml::parseSearchJourney(QNetworkReply *networkReply) const QDomNodeList connections = doc.elementsByTagName("Connection"); for (int i = 0; i < connections.count(); ++i) { - JourneyResultItem *item = new JourneyResultItem(); + JourneyResultItem *item = new JourneyResultItem(lastJourneyResultList); item->setId(connections.at(i).toElement().attribute("id").trimmed()); QDomElement overview = connections.at(i).firstChildElement("Overview"); @@ -846,7 +846,7 @@ JourneyDetailResultList* ParserHafasXml::internalParseJourneyDetails(const QDomE const QDomNodeList sections = connection.elementsByTagName("ConSection"); for (int i = 0; i < sections.count(); ++i) { - JourneyDetailResultItem *item = new JourneyDetailResultItem(); + JourneyDetailResultItem *item = new JourneyDetailResultItem(results); const QDomNode section = sections.at(i); QDomElement stop; diff --git a/src/parser/parser_xmlvasttrafikse.cpp b/src/parser/parser_xmlvasttrafikse.cpp index 75534115..f702413c 100644 --- a/src/parser/parser_xmlvasttrafikse.cpp +++ b/src/parser/parser_xmlvasttrafikse.cpp @@ -329,7 +329,7 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) if (doc.setContent(xmlRawtext, false)) { QDomNodeList tripNodeList = doc.elementsByTagName("Trip"); for (unsigned int i = 0; i < tripNodeList.length(); ++i) { - JourneyResultItem *jritem = new JourneyResultItem(); + JourneyResultItem *jritem = new JourneyResultItem(journeyResultList); JourneyDetailResultList *detailsList = new JourneyDetailResultList(); /// Set default values for journey's start and end time @@ -367,7 +367,7 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) trainTypes.append(i18nConnectionType(getAttribute(legNode, "name"))); } - JourneyDetailResultItem *jdrItem = new JourneyDetailResultItem(); + JourneyDetailResultItem *jdrItem = new JourneyDetailResultItem(detailsList); jdrItem->setDepartureStation(getAttribute(originNode, "name")); const QString depTrack = getAttribute(originNode, "track"); jdrItem->setDepartureInfo(depTrack.isEmpty() ? QChar(0x2014) : tr("Track %1").arg(depTrack)); From c01f35fceee44645a306fdb2b062b8d7019038ec Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 25 May 2015 00:46:48 +0200 Subject: [PATCH 15/85] added missed parents --- src/parser/parser_ninetwo.cpp | 4 ++-- src/parser/parser_resrobot.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/parser/parser_ninetwo.cpp b/src/parser/parser_ninetwo.cpp index 0386775d..4dd83937 100644 --- a/src/parser/parser_ninetwo.cpp +++ b/src/parser/parser_ninetwo.cpp @@ -345,7 +345,7 @@ void ParserNinetwo::parseSearchJourney(QNetworkReply *networkReply) for (i = journeys.constBegin(); i != journeys.constEnd(); ++i) { QVariantMap journey = i->toMap(); parseJourneyOption(journey); - JourneyResultItem* item = new JourneyResultItem; + JourneyResultItem* item = new JourneyResultItem(result); arrival = QDateTime::fromString(journey.value("arrival").toString(), "yyyy-MM-ddTHH:mm"); departure = QDateTime::fromString(journey.value("departure").toString(), "yyyy-MM-ddTHH:mm"); @@ -424,7 +424,7 @@ void ParserNinetwo::parseJourneyOption(const QVariantMap &object) for(int i = 0; i < legs.count(); i++) { QVariantMap leg = legs.at(i).toMap(); - JourneyDetailResultItem* resultItem = new JourneyDetailResultItem; + JourneyDetailResultItem* resultItem = new JourneyDetailResultItem(result); QVariantList stops = leg.value("stops").toList(); diff --git a/src/parser/parser_resrobot.cpp b/src/parser/parser_resrobot.cpp index c0fbc0cb..40e97a56 100644 --- a/src/parser/parser_resrobot.cpp +++ b/src/parser/parser_resrobot.cpp @@ -479,7 +479,7 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) else if (arrDayDiff < 0) arrTime += QString::number(arrDayDiff); - JourneyResultItem* journey = new JourneyResultItem; + JourneyResultItem* journey = new JourneyResultItem(result); journey->setId(journeyID); journey->setDate(segments.first()->departureDateTime().date()); journey->setDepartureTime(depTime); @@ -523,7 +523,7 @@ QList ParserResRobot::parseJourneySegments(const QVari foreach (QVariant segmentData, segments) { QVariantMap segment = segmentData.toMap(); - JourneyDetailResultItem* resultItem = new JourneyDetailResultItem; + JourneyDetailResultItem* resultItem = new JourneyDetailResultItem(results); // Departure QVariantMap departure = segment.value("departure").toMap(); From 90dc51c7a7aa54b26d9bb3374019162513272698 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 25 May 2015 01:02:20 +0200 Subject: [PATCH 16/85] not that easy there, leaving a FIXME for the next round --- src/parser/parser_resrobot.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/parser/parser_resrobot.cpp b/src/parser/parser_resrobot.cpp index 40e97a56..f2b1b1ab 100644 --- a/src/parser/parser_resrobot.cpp +++ b/src/parser/parser_resrobot.cpp @@ -479,7 +479,7 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) else if (arrDayDiff < 0) arrTime += QString::number(arrDayDiff); - JourneyResultItem* journey = new JourneyResultItem(result); + JourneyResultItem* journey = new JourneyResultItem(journeyList); journey->setId(journeyID); journey->setDate(segments.first()->departureDateTime().date()); journey->setDepartureTime(depTime); @@ -523,7 +523,7 @@ QList ParserResRobot::parseJourneySegments(const QVari foreach (QVariant segmentData, segments) { QVariantMap segment = segmentData.toMap(); - JourneyDetailResultItem* resultItem = new JourneyDetailResultItem(results); + JourneyDetailResultItem* resultItem = new JourneyDetailResultItem;//FIXME will leak in QML // Departure QVariantMap departure = segment.value("departure").toMap(); From 491f62f29369b39c9dd7cd2459a787ccc1a8f3b4 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Thu, 28 May 2015 02:12:07 +0200 Subject: [PATCH 17/85] added missing destructors --- src/parser/parser_definitions.cpp | 20 ++++++++++++++++++++ src/parser/parser_definitions.h | 4 ++++ 2 files changed, 24 insertions(+) diff --git a/src/parser/parser_definitions.cpp b/src/parser/parser_definitions.cpp index 970fcce5..8976bf51 100644 --- a/src/parser/parser_definitions.cpp +++ b/src/parser/parser_definitions.cpp @@ -71,6 +71,16 @@ TimetableEntry::TimetableEntry() //------------- JourneyResultList +JourneyResultList::JourneyResultList(QObject * parent) : QObject(parent) +{ + +} + +JourneyResultList::~JourneyResultList() +{ + qDeleteAll(m_items); +} + qreal JourneyResultList::itemcount() { return m_items.count(); @@ -234,6 +244,16 @@ void JourneyResultItem::setInternalData2(const QString &internalData2) //------------- JourneyDetailResultList +JourneyDetailResultList::JourneyDetailResultList(QObject * parent) : QObject(parent) +{ + +} + +JourneyDetailResultList::~JourneyDetailResultList() +{ + qDeleteAll(m_items); +} + QString JourneyDetailResultList::id() const { return m_id; diff --git a/src/parser/parser_definitions.h b/src/parser/parser_definitions.h index 94278a1e..e15d1620 100644 --- a/src/parser/parser_definitions.h +++ b/src/parser/parser_definitions.h @@ -141,6 +141,8 @@ class JourneyResultList : public QObject public slots: JourneyResultItem *getItem(int); public: + explicit JourneyResultList(QObject * parent = 0); + virtual ~JourneyResultList(); void appendItem(JourneyResultItem *item); qreal itemcount(); QString departureStation() const; @@ -230,6 +232,8 @@ class JourneyDetailResultList : public QObject public slots: JourneyDetailResultItem *getItem(int); public: + explicit JourneyDetailResultList(QObject * parent = 0); + virtual ~JourneyDetailResultList(); void appendItem(JourneyDetailResultItem *item); qreal itemcount(); QString id() const; From 1c97540a3cc6029a6b30c9ef53497b1678b29c3f Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Thu, 28 May 2015 02:13:38 +0200 Subject: [PATCH 18/85] fixing leaks --- src/parser/parser_hafasbinary.cpp | 9 +++++---- src/parser/parser_hafasxml.cpp | 24 ++++++++++++++++++++++-- src/parser/parser_hafasxml.h | 2 ++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/parser/parser_hafasbinary.cpp b/src/parser/parser_hafasbinary.cpp index 7fafab07..a6105885 100644 --- a/src/parser/parser_hafasbinary.cpp +++ b/src/parser/parser_hafasbinary.cpp @@ -43,7 +43,8 @@ void ParserHafasBinary::searchJourney(const Station &departureStation, const Sta currentRequestState = FahrplanNS::searchJourneyRequest; hafasContext.seqNr = ""; - lastJourneyResultList = NULL; + + cleanupJourney(); QString trainrestr = getTrainRestrictionsCodes(trainrestrictions); @@ -85,8 +86,8 @@ void ParserHafasBinary::searchJourney(const Station &departureStation, const Sta void ParserHafasBinary::parseSearchJourney(QNetworkReply *networkReply) { - lastJourneyResultList = new JourneyResultList(); - journeyDetailInlineData.clear(); + lastJourneyResultList = new JourneyResultList(this); + stringCache.clear(); QByteArray tmpBuffer = networkReply->readAll(); @@ -324,7 +325,7 @@ void ParserHafasBinary::parseSearchJourney(QNetworkReply *networkReply) qDebug()<<"conId"<readAll())) diff --git a/src/parser/parser_hafasxml.h b/src/parser/parser_hafasxml.h index aee85971..6ad4a46e 100644 --- a/src/parser/parser_hafasxml.h +++ b/src/parser/parser_hafasxml.h @@ -57,6 +57,7 @@ class ParserHafasXml : public ParserAbstract Q_OBJECT public: explicit ParserHafasXml(QObject *parent = 0); + virtual ~ParserHafasXml(); static QString getName() { return "HafasXML"; } virtual QString name() { return getName(); } virtual QString shortName() { return getName(); } @@ -90,6 +91,7 @@ public slots: void parseSearchLaterJourney(QNetworkReply *networkReply); void parseSearchEarlierJourney(QNetworkReply *networkReply); void parseJourneyDetails(QNetworkReply *networkReply); + void cleanupJourney(); virtual QString getTrainRestrictionsCodes(int trainrestrictions); JourneyResultList *lastJourneyResultList; From ca2363e8f9350af597dd41076b0fbd68ec0e40ae Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Thu, 28 May 2015 02:15:47 +0200 Subject: [PATCH 19/85] ownership, concurrency and and destructor for parser backend manager and thread --- src/fahrplan_backend_manager.cpp | 10 +++++++++- src/fahrplan_backend_manager.h | 1 + src/fahrplan_parser_thread.h | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/fahrplan_backend_manager.cpp b/src/fahrplan_backend_manager.cpp index 732357bb..aed57f55 100644 --- a/src/fahrplan_backend_manager.cpp +++ b/src/fahrplan_backend_manager.cpp @@ -26,6 +26,14 @@ FahrplanBackendManager::FahrplanBackendManager(int defaultParser, QObject *paren currentParserIndex = defaultParser; } +FahrplanBackendManager::~FahrplanBackendManager() +{ + if (m_parser) { + // Parser object will be autodeleted after the thread quits. + m_parser->quit(); + } +} + QStringList FahrplanBackendManager::getParserList() { QStringList result; @@ -68,7 +76,7 @@ void FahrplanBackendManager::setParser(int index) m_parser->quit(); } - m_parser = new FahrplanParserThread(); + m_parser = new FahrplanParserThread(this); m_parser->init(index); emit parserChanged(m_parser->name(), currentParserIndex); diff --git a/src/fahrplan_backend_manager.h b/src/fahrplan_backend_manager.h index fc7797b9..1672cc8f 100644 --- a/src/fahrplan_backend_manager.h +++ b/src/fahrplan_backend_manager.h @@ -28,6 +28,7 @@ class FahrplanBackendManager : public QObject public: explicit FahrplanBackendManager(int defaultParser, QObject *parent = 0); + virtual ~FahrplanBackendManager(); QStringList getParserList(); void setParser(int index); FahrplanParserThread *getParser(); diff --git a/src/fahrplan_parser_thread.h b/src/fahrplan_parser_thread.h index 8072f1ee..90a3d758 100644 --- a/src/fahrplan_parser_thread.h +++ b/src/fahrplan_parser_thread.h @@ -89,7 +89,7 @@ public slots: void run(); private: - bool m_ready; + volatile bool m_ready; int i_parser; QStringList m_trainrestrictions; From 6ab36b3f51473091fad8fd6973147f911e671542 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Sun, 31 May 2015 23:27:52 +0200 Subject: [PATCH 20/85] clearJourney() is a more proper name --- src/parser/parser_hafasbinary.cpp | 2 +- src/parser/parser_hafasxml.cpp | 6 +++--- src/parser/parser_hafasxml.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/parser/parser_hafasbinary.cpp b/src/parser/parser_hafasbinary.cpp index a6105885..5c57dd78 100644 --- a/src/parser/parser_hafasbinary.cpp +++ b/src/parser/parser_hafasbinary.cpp @@ -44,7 +44,7 @@ void ParserHafasBinary::searchJourney(const Station &departureStation, const Sta currentRequestState = FahrplanNS::searchJourneyRequest; hafasContext.seqNr = ""; - cleanupJourney(); + clearJourney(); QString trainrestr = getTrainRestrictionsCodes(trainrestrictions); diff --git a/src/parser/parser_hafasxml.cpp b/src/parser/parser_hafasxml.cpp index f89f7c85..ec0ec1cf 100644 --- a/src/parser/parser_hafasxml.cpp +++ b/src/parser/parser_hafasxml.cpp @@ -54,10 +54,10 @@ ParserHafasXml::ParserHafasXml(QObject *parent) : ParserHafasXml::~ParserHafasXml() { - cleanupJourney(); + clearJourney(); } -void ParserHafasXml::cleanupJourney() +void ParserHafasXml::clearJourney() { if (lastJourneyResultList) { delete lastJourneyResultList; @@ -539,7 +539,7 @@ void ParserHafasXml::searchJourney(const Station &departureStation, const Statio currentRequestState = FahrplanNS::searchJourneyRequest; hafasContext.seqNr = ""; - cleanupJourney(); + clearJourney(); QString trainrestr = getTrainRestrictionsCodes(trainrestrictions); diff --git a/src/parser/parser_hafasxml.h b/src/parser/parser_hafasxml.h index 6ad4a46e..513d206a 100644 --- a/src/parser/parser_hafasxml.h +++ b/src/parser/parser_hafasxml.h @@ -75,6 +75,7 @@ public slots: bool supportsTimeTable(); bool supportsTimeTableDirection(); QStringList getTrainRestrictions(); + virtual void clearJourney(); protected: QString baseXmlUrl; @@ -91,7 +92,6 @@ public slots: void parseSearchLaterJourney(QNetworkReply *networkReply); void parseSearchEarlierJourney(QNetworkReply *networkReply); void parseJourneyDetails(QNetworkReply *networkReply); - void cleanupJourney(); virtual QString getTrainRestrictionsCodes(int trainrestrictions); JourneyResultList *lastJourneyResultList; From f564acb964bf334d2bb0f3b93a6bb2efc09c6283 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Sun, 31 May 2015 23:29:41 +0200 Subject: [PATCH 21/85] adding clearJourney to EFA parser --- src/parser/parser_efa.cpp | 15 +++++++++++++++ src/parser/parser_efa.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/src/parser/parser_efa.cpp b/src/parser/parser_efa.cpp index 0ed6c2b5..3fe3a3a4 100755 --- a/src/parser/parser_efa.cpp +++ b/src/parser/parser_efa.cpp @@ -108,6 +108,19 @@ ParserEFA::ParserEFA(QObject *parent) : m_timeTableForStationParameters.isValid = false; } +ParserEFA::~ParserEFA() +{ + clearJourney(); +} + +void ParserEFA::clearJourney() +{ + if (lastJourneyResultList) { + delete lastJourneyResultList; + lastJourneyResultList = NULL; + } +} + bool ParserEFA::supportsGps() { return true; @@ -504,6 +517,8 @@ void ParserEFA::searchJourney(const Station &departureStation, const Station &vi void ParserEFA::parseSearchJourney(QNetworkReply *networkReply) { qDebug() << "ParserEFA::parseSearchJourney(QNetworkReply *networkReply)"; + clearJourney(); + lastJourneyResultList = new JourneyResultList(); for (QHash::Iterator it = cachedJourneyDetailsEfa.begin(); it != cachedJourneyDetailsEfa.end();) { diff --git a/src/parser/parser_efa.h b/src/parser/parser_efa.h index 1ce9573b..c31e3cfc 100755 --- a/src/parser/parser_efa.h +++ b/src/parser/parser_efa.h @@ -29,6 +29,7 @@ class ParserEFA : public ParserAbstract Q_OBJECT public: explicit ParserEFA(QObject *parent = 0); + virtual ~ParserEFA(); static QString getName() { return "EFA"; } virtual QString name() { return getName(); } virtual QString shortName() { return getName(); } @@ -47,6 +48,7 @@ public slots: bool supportsTimeTableDirection(); void checkForError(QDomDocument *serverReplyDomDoc); QStringList getTrainRestrictions(); + virtual void clearJourney(); protected: QString baseRestUrl; From 4e9d1506bf20f87ae55d96a6c268f812baa40f80 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 1 Jun 2015 00:05:17 +0200 Subject: [PATCH 22/85] fixing ParserXmlVasttrafikSe memory leaks --- src/parser/parser_xmlvasttrafikse.cpp | 69 ++++++++++++++++----------- src/parser/parser_xmlvasttrafikse.h | 4 ++ 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/src/parser/parser_xmlvasttrafikse.cpp b/src/parser/parser_xmlvasttrafikse.cpp index f702413c..b99e7d58 100644 --- a/src/parser/parser_xmlvasttrafikse.cpp +++ b/src/parser/parser_xmlvasttrafikse.cpp @@ -46,6 +46,18 @@ ParserXmlVasttrafikSe::ParserXmlVasttrafikSe(QObject *parent) m_timeTableForStationParameters.isValid = false; } +ParserXmlVasttrafikSe::~ParserXmlVasttrafikSe() +{ + clearJourney(); +} + +void ParserXmlVasttrafikSe::clearJourney() +{ + if (lastJourneyResultList) { + delete lastJourneyResultList; + lastJourneyResultList = NULL; + } +} void ParserXmlVasttrafikSe::getTimeTableForStation(const Station ¤tStation, const Station &, const QDateTime &dateTime, Mode mode, int) { @@ -305,7 +317,8 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) { qDebug() << "ParserXmlVasttrafikSe::parseSearchJourney(networkReply.url()=" << networkReply->url().toString() << ")"; - JourneyResultList *journeyResultList = new JourneyResultList(); + clearJourney(); + lastJourneyResultList = new JourneyResultList(this); for (QHash::Iterator it = cachedJourneyDetails.begin(); it != cachedJourneyDetails.end();) { JourneyDetailResultList *jdrl = it.value(); @@ -314,11 +327,11 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) } /// Use fallback values for empty results (i.e. no connections found) - journeyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); - journeyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); - journeyResultList->setArrivalStation(m_searchJourneyParameters.arrivalStation.name); + lastJourneyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); + lastJourneyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); + lastJourneyResultList->setArrivalStation(m_searchJourneyParameters.arrivalStation.name); //: DATE, TIME - journeyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(m_searchJourneyParameters.dateTime.date().toString(Qt::DefaultLocaleShortDate)).arg(m_searchJourneyParameters.dateTime.time().toString(Qt::DefaultLocaleShortDate))); + lastJourneyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(m_searchJourneyParameters.dateTime.date().toString(Qt::DefaultLocaleShortDate)).arg(m_searchJourneyParameters.dateTime.time().toString(Qt::DefaultLocaleShortDate))); m_earliestArrival = m_latestResultDeparture = QDateTime(); @@ -329,8 +342,8 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) if (doc.setContent(xmlRawtext, false)) { QDomNodeList tripNodeList = doc.elementsByTagName("Trip"); for (unsigned int i = 0; i < tripNodeList.length(); ++i) { - JourneyResultItem *jritem = new JourneyResultItem(journeyResultList); - JourneyDetailResultList *detailsList = new JourneyDetailResultList(); + JourneyResultItem *jritem = new JourneyResultItem(lastJourneyResultList); + JourneyDetailResultList *detailsList = new JourneyDetailResultList(this); /// Set default values for journey's start and end time QDateTime journeyStart = QDateTime::currentDateTime(); @@ -351,15 +364,15 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) journeyStart.setTime(time); if (i == 0) { const QDate date = QDate::fromString(getAttribute(originNode, "date"), QLatin1String("yyyy-MM-dd")); - journeyResultList->setDepartureStation(getAttribute(originNode, "name")); + lastJourneyResultList->setDepartureStation(getAttribute(originNode, "name")); //: DATE, TIME - journeyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(date.toString(Qt::DefaultLocaleShortDate)).arg(time.toString(Qt::DefaultLocaleShortDate))); + lastJourneyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(date.toString(Qt::DefaultLocaleShortDate)).arg(time.toString(Qt::DefaultLocaleShortDate))); } } if (j == legNodeList.length() - 1) { journeyEnd.setTime(QTime::fromString(getAttribute(destinationNode, "time"), "hh:mm")); if (i == 0) - journeyResultList->setArrivalStation(getAttribute(destinationNode, "name")); + lastJourneyResultList->setArrivalStation(getAttribute(destinationNode, "name")); } if (getAttribute(legNode, "type") != QLatin1String("WALK") || getAttribute(originNode, "name") != getAttribute(destinationNode, "name")) { @@ -441,14 +454,14 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) else if (tripRtStatus == TRIP_RTDATA_ONTIME) jritem->setMiscInfo(tr("on time")); - journeyResultList->appendItem(jritem); + lastJourneyResultList->appendItem(jritem); const QString id = QString::number(i); jritem->setId(id); detailsList->setId(id); - detailsList->setDepartureStation(journeyResultList->departureStation()); - detailsList->setViaStation(journeyResultList->viaStation()); - detailsList->setArrivalStation(journeyResultList->arrivalStation()); + detailsList->setDepartureStation(lastJourneyResultList->departureStation()); + detailsList->setViaStation(lastJourneyResultList->viaStation()); + detailsList->setArrivalStation(lastJourneyResultList->arrivalStation()); detailsList->setDuration(jritem->duration()); detailsList->setArrivalDateTime(journeyEnd); detailsList->setDepartureDateTime(journeyStart); @@ -461,7 +474,7 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) } } - emit journeyResult(journeyResultList); + emit journeyResult(lastJourneyResultList); } void ParserXmlVasttrafikSe::searchJourneyLater() @@ -469,13 +482,14 @@ void ParserXmlVasttrafikSe::searchJourneyLater() if (m_latestResultDeparture.isValid()) searchJourney(m_searchJourneyParameters.departureStation, m_searchJourneyParameters.arrivalStation, m_searchJourneyParameters.viaStation, m_latestResultDeparture, Departure, 0); else { - JourneyResultList *journeyResultList = new JourneyResultList(); - journeyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); - journeyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); - journeyResultList->setArrivalStation(m_searchJourneyParameters.arrivalStation.name); + clearJourney(); + lastJourneyResultList = new JourneyResultList(); + lastJourneyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); + lastJourneyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); + lastJourneyResultList->setArrivalStation(m_searchJourneyParameters.arrivalStation.name); //: DATE, TIME - journeyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(m_searchJourneyParameters.dateTime.date().toString(Qt::DefaultLocaleShortDate)).arg(m_searchJourneyParameters.dateTime.time().toString(Qt::DefaultLocaleShortDate))); - emit journeyResult(journeyResultList); + lastJourneyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(m_searchJourneyParameters.dateTime.date().toString(Qt::DefaultLocaleShortDate)).arg(m_searchJourneyParameters.dateTime.time().toString(Qt::DefaultLocaleShortDate))); + emit journeyResult(lastJourneyResultList); } } @@ -484,13 +498,14 @@ void ParserXmlVasttrafikSe::searchJourneyEarlier() if (m_earliestArrival.isValid()) searchJourney(m_searchJourneyParameters.departureStation, m_searchJourneyParameters.arrivalStation, m_searchJourneyParameters.viaStation, m_earliestArrival, Arrival, 0); else { - JourneyResultList *journeyResultList = new JourneyResultList(); - journeyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); - journeyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); - journeyResultList->setArrivalStation(m_searchJourneyParameters.arrivalStation.name); + clearJourney(); + lastJourneyResultList = new JourneyResultList(); + lastJourneyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); + lastJourneyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); + lastJourneyResultList->setArrivalStation(m_searchJourneyParameters.arrivalStation.name); //: DATE, TIME - journeyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(m_searchJourneyParameters.dateTime.date().toString(Qt::DefaultLocaleShortDate)).arg(m_searchJourneyParameters.dateTime.time().toString(Qt::DefaultLocaleShortDate))); - emit journeyResult(journeyResultList); + lastJourneyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(m_searchJourneyParameters.dateTime.date().toString(Qt::DefaultLocaleShortDate)).arg(m_searchJourneyParameters.dateTime.time().toString(Qt::DefaultLocaleShortDate))); + emit journeyResult(lastJourneyResultList); } } diff --git a/src/parser/parser_xmlvasttrafikse.h b/src/parser/parser_xmlvasttrafikse.h index c75004eb..238b6435 100644 --- a/src/parser/parser_xmlvasttrafikse.h +++ b/src/parser/parser_xmlvasttrafikse.h @@ -28,6 +28,7 @@ class ParserXmlVasttrafikSe : public ParserAbstract public: explicit ParserXmlVasttrafikSe(QObject *parent = 0); + virtual ~ParserXmlVasttrafikSe(); static QString getName() { return QString("%1 (vasttrafik.se)").arg(tr("Sweden")); } virtual QString name() { return getName(); } virtual QString shortName() { return "vasttrafik.se"; } @@ -46,6 +47,7 @@ public slots: virtual bool supportsTimeTableDirection(); // virtual QStringList getTrainRestrictions(); // void cancelRequest(); + virtual void clearJourney(); protected: virtual void parseStationsByName(QNetworkReply *networkReply); @@ -53,6 +55,8 @@ public slots: virtual void parseTimeTable(QNetworkReply *networkReply); virtual void parseSearchJourney(QNetworkReply *networkReply); + JourneyResultList *lastJourneyResultList; + private: static const qlonglong TRIP_RTDATA_NONE; static const qlonglong TRIP_RTDATA_ONTIME; From 88e23bd05192a7b33274352b25ae55d9ade6c696 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 1 Jun 2015 00:28:42 +0200 Subject: [PATCH 23/85] one more small fix to vasttrafikse --- src/parser/parser_xmlvasttrafikse.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/parser/parser_xmlvasttrafikse.cpp b/src/parser/parser_xmlvasttrafikse.cpp index b99e7d58..02e682b1 100644 --- a/src/parser/parser_xmlvasttrafikse.cpp +++ b/src/parser/parser_xmlvasttrafikse.cpp @@ -57,6 +57,12 @@ void ParserXmlVasttrafikSe::clearJourney() delete lastJourneyResultList; lastJourneyResultList = NULL; } + + for (QHash::Iterator it = cachedJourneyDetails.begin(); it != cachedJourneyDetails.end();) { + JourneyDetailResultList *jdrl = it.value(); + it = cachedJourneyDetails.erase(it); + delete jdrl; + } } void ParserXmlVasttrafikSe::getTimeTableForStation(const Station ¤tStation, const Station &, const QDateTime &dateTime, Mode mode, int) @@ -320,12 +326,6 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) clearJourney(); lastJourneyResultList = new JourneyResultList(this); - for (QHash::Iterator it = cachedJourneyDetails.begin(); it != cachedJourneyDetails.end();) { - JourneyDetailResultList *jdrl = it.value(); - it = cachedJourneyDetails.erase(it); - delete jdrl; - } - /// Use fallback values for empty results (i.e. no connections found) lastJourneyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); lastJourneyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); From 7f7411de09a399e50f72e7f957a5724eafae28b3 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 1 Jun 2015 00:29:10 +0200 Subject: [PATCH 24/85] fixing ninetwo memory leaks --- src/parser/parser_ninetwo.cpp | 39 +++++++++++++++++++++++++++-------- src/parser/parser_ninetwo.h | 4 ++++ 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/parser/parser_ninetwo.cpp b/src/parser/parser_ninetwo.cpp index 4dd83937..95d88b2f 100644 --- a/src/parser/parser_ninetwo.cpp +++ b/src/parser/parser_ninetwo.cpp @@ -54,6 +54,25 @@ ParserNinetwo::ParserNinetwo(QObject *parent):ParserAbstract(parent) lastCoordinates.isValid = false; } +ParserNinetwo::~ParserNinetwo() +{ + clearJourney(); +} + +void ParserNinetwo::clearJourney() +{ + if (lastJourneyResultList) { + delete lastJourneyResultList; + lastJourneyResultList = NULL; + } + + for (QMap::Iterator it = cachedResults.begin(); it != cachedResults.end();) { + JourneyDetailResultList *jdrl = it.value(); + it = cachedResults.erase(it); + delete jdrl; + } +} + void ParserNinetwo::getTimeTableForStation(const Station ¤tStation, const Station &, const QDateTime &, @@ -336,7 +355,9 @@ void ParserNinetwo::parseSearchJourney(QNetworkReply *networkReply) QVariantList journeys = doc.value("journeys").toList(); - JourneyResultList* result=new JourneyResultList; + clearJourney(); + + lastJourneyResultList = new JourneyResultList(this); QDateTime arrival; QDateTime departure; @@ -345,7 +366,7 @@ void ParserNinetwo::parseSearchJourney(QNetworkReply *networkReply) for (i = journeys.constBegin(); i != journeys.constEnd(); ++i) { QVariantMap journey = i->toMap(); parseJourneyOption(journey); - JourneyResultItem* item = new JourneyResultItem(result); + JourneyResultItem* item = new JourneyResultItem(lastJourneyResultList); arrival = QDateTime::fromString(journey.value("arrival").toString(), "yyyy-MM-ddTHH:mm"); departure = QDateTime::fromString(journey.value("departure").toString(), "yyyy-MM-ddTHH:mm"); @@ -376,17 +397,17 @@ void ParserNinetwo::parseSearchJourney(QNetworkReply *networkReply) int minutes = departure.secsTo(arrival)/60; item->setDuration(QString("%1:%2").arg(minutes/60).arg(minutes%60,2,10,QChar('0'))); item->setId(journey.value("id").toString()); - result->appendItem(item); + lastJourneyResultList ->appendItem(item); //Set result metadata based on first result - if (result->itemcount() == 1) { - result->setTimeInfo(arrival.date().toString()); - result->setDepartureStation(cachedResults[item->id()]->departureStation()); - result->setArrivalStation(cachedResults[item->id()]->arrivalStation()); + if (lastJourneyResultList ->itemcount() == 1) { + lastJourneyResultList ->setTimeInfo(arrival.date().toString()); + lastJourneyResultList ->setDepartureStation(cachedResults[item->id()]->departureStation()); + lastJourneyResultList ->setArrivalStation(cachedResults[item->id()]->arrivalStation()); } } lastsearch.lastOption=departure; - emit journeyResult(result); + emit journeyResult(lastJourneyResultList ); } void ParserNinetwo::parseSearchLaterJourney(QNetworkReply *) @@ -406,7 +427,7 @@ void ParserNinetwo::parseJourneyDetails(QNetworkReply *) void ParserNinetwo::parseJourneyOption(const QVariantMap &object) { - JourneyDetailResultList* result = new JourneyDetailResultList; + JourneyDetailResultList* result = new JourneyDetailResultList(this); QString id = object.value("id").toString(); QVariantList legs = object.value("legs").toList(); diff --git a/src/parser/parser_ninetwo.h b/src/parser/parser_ninetwo.h index a58c95e9..e142004f 100644 --- a/src/parser/parser_ninetwo.h +++ b/src/parser/parser_ninetwo.h @@ -60,6 +60,7 @@ class ParserNinetwo : public ParserAbstract public: ParserNinetwo(QObject* parent = 0); + virtual ~ParserNinetwo(); // ParserAbstract interface public: @@ -80,6 +81,7 @@ public slots: bool supportsTimeTable() { return true; } bool supportsTimeTableDirection() { return false; } QStringList getTrainRestrictions(); + virtual void clearJourney(); protected: void parseTimeTable(QNetworkReply *networkReply); @@ -91,6 +93,8 @@ public slots: void parseJourneyDetails(QNetworkReply *networkReply); QMap cachedResults; + JourneyResultList *lastJourneyResultList; + private: void parseJourneyOption(const QVariantMap &object); }; From ae0c3f567d63dae6d000b3183cbd608e71014165 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 1 Jun 2015 00:29:31 +0200 Subject: [PATCH 25/85] fixing resrobot memory leaks --- src/parser/parser_resrobot.cpp | 30 ++++++++++++++++++++++-------- src/parser/parser_resrobot.h | 4 ++++ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/parser/parser_resrobot.cpp b/src/parser/parser_resrobot.cpp index f2b1b1ab..d097fbb5 100644 --- a/src/parser/parser_resrobot.cpp +++ b/src/parser/parser_resrobot.cpp @@ -87,6 +87,19 @@ ParserResRobot::ParserResRobot(QObject *parent) : transportModeStrings[QString::fromUtf8("Γ–vriga tΓ₯g")] = tr("Other train"); } +ParserResRobot::~ParserResRobot() +{ + clearJourney(); +} + +void ParserResRobot::clearJourney() +{ + if (lastJourneyResultList) { + delete lastJourneyResultList; + lastJourneyResultList = NULL; + } +} + bool ParserResRobot::supportsGps() { return true; @@ -430,7 +443,8 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) cachedResults.clear(); - JourneyResultList *journeyList = new JourneyResultList(); + clearJourney(); + lastJourneyResultList = new JourneyResultList(this); int journeyCounter = 0; foreach (QVariant journeyData, journeyListData) { @@ -454,7 +468,7 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) if (transportModes.count() == 0 && segments.count() == 1) transportModes.append(segments.first()->train()); - JourneyDetailResultList* journeyDetails = new JourneyDetailResultList; + JourneyDetailResultList* journeyDetails = new JourneyDetailResultList(this); foreach (JourneyDetailResultItem* segment, segments) journeyDetails->appendItem(segment); journeyDetails->setId(journeyID); @@ -479,7 +493,7 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) else if (arrDayDiff < 0) arrTime += QString::number(arrDayDiff); - JourneyResultItem* journey = new JourneyResultItem(journeyList); + JourneyResultItem* journey = new JourneyResultItem(lastJourneyResultList); journey->setId(journeyID); journey->setDate(segments.first()->departureDateTime().date()); journey->setDepartureTime(depTime); @@ -487,7 +501,7 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) journey->setTrainType(transportModes.join(", ")); journey->setDuration(duration); journey->setTransfers(QString::number(transportModes.count()-1)); - journeyList->appendItem(journey); + lastJourneyResultList->appendItem(journey); if (journeyCounter == 0) { if (lastJourneySearch.mode == Departure) @@ -502,16 +516,16 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) ++journeyCounter; } - journeyList->setDepartureStation(lastJourneySearch.from.name); - journeyList->setArrivalStation(lastJourneySearch.to.name); + lastJourneyResultList->setDepartureStation(lastJourneySearch.from.name); + lastJourneyResultList->setArrivalStation(lastJourneySearch.to.name); QString modeString; if (lastJourneySearch.mode == Arrival) modeString = tr("Arrivals"); else modeString = tr("Departures"); - journeyList->setTimeInfo(modeString + " " + lastJourneySearch.dateTime.toString(tr("ddd MMM d, HH:mm"))); + lastJourneyResultList->setTimeInfo(modeString + " " + lastJourneySearch.dateTime.toString(tr("ddd MMM d, HH:mm"))); - emit journeyResult(journeyList); + emit journeyResult(lastJourneyResultList); } // Parse info about one journey option. Store detailed info about segments for later use. diff --git a/src/parser/parser_resrobot.h b/src/parser/parser_resrobot.h index 3ddef51a..9d17664b 100644 --- a/src/parser/parser_resrobot.h +++ b/src/parser/parser_resrobot.h @@ -60,6 +60,7 @@ class ParserResRobot : public ParserAbstract Q_OBJECT public: explicit ParserResRobot(QObject *parent = 0); + virtual ~ParserResRobot(); static QString getName() { return QString("%1 (resrobot.se)").arg(tr("Sweden")); } virtual QString name() { return getName(); } @@ -84,6 +85,7 @@ public slots: virtual void searchJourneyLater(); virtual void searchJourneyEarlier(); virtual void getJourneyDetails(const QString &id); + virtual void clearJourney(); protected: virtual void parseTimeTable(QNetworkReply *networkReply); @@ -94,6 +96,8 @@ public slots: virtual void parseSearchEarlierJourney(QNetworkReply *networkReply); virtual void parseJourneyDetails(QNetworkReply *networkReply); + JourneyResultList *lastJourneyResultList; + private: enum transportModePreset { ALL_TRANSPORT_MODES, From 9578c88b377a2c497d59032a712c202e3cc86d33 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 1 Jun 2015 00:33:23 +0200 Subject: [PATCH 26/85] providing clearJourney at the top level --- src/parser/parser_abstract.cpp | 8 +++++++- src/parser/parser_abstract.h | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/parser/parser_abstract.cpp b/src/parser/parser_abstract.cpp index 86ade9e1..a9c99bd9 100644 --- a/src/parser/parser_abstract.cpp +++ b/src/parser/parser_abstract.cpp @@ -43,7 +43,7 @@ ParserAbstract::ParserAbstract(QObject *parent) : currentRequestState = FahrplanNS::noneRequest; - requestTimeout = new QTimer(); + requestTimeout = new QTimer(this); connect(requestTimeout, SIGNAL(timeout()), this, SLOT(networkReplyTimedOut())); @@ -52,10 +52,16 @@ ParserAbstract::ParserAbstract(QObject *parent) : ParserAbstract::~ParserAbstract() { + clearJourney(); delete requestTimeout; delete NetworkManager; } +void ParserAbstract::clearJourney() +{ + +} + void ParserAbstract::networkReplyFinished(QNetworkReply *networkReply) { FahrplanNS::curReqStates internalRequestState = currentRequestState; diff --git a/src/parser/parser_abstract.h b/src/parser/parser_abstract.h index 969799ad..af236afd 100644 --- a/src/parser/parser_abstract.h +++ b/src/parser/parser_abstract.h @@ -37,7 +37,7 @@ class ParserAbstract : public QObject enum Mode { Departure = 0, Arrival = 1 }; explicit ParserAbstract(QObject *parent = 0); - ~ParserAbstract(); + virtual ~ParserAbstract(); static QString getName() { return "Abstract"; } virtual QString name() { return getName(); } @@ -58,6 +58,7 @@ public slots: virtual bool supportsTimeTableDirection(); virtual QStringList getTrainRestrictions(); void cancelRequest(); + virtual void clearJourney(); signals: void stationsResult(const StationsList &result); From 17bc132044434f47f0b4db567e6d44d5cbb36e53 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 25 May 2015 00:46:48 +0200 Subject: [PATCH 27/85] added missed parents --- src/parser/parser_resrobot.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/parser/parser_resrobot.cpp b/src/parser/parser_resrobot.cpp index d097fbb5..9af730ab 100644 --- a/src/parser/parser_resrobot.cpp +++ b/src/parser/parser_resrobot.cpp @@ -537,7 +537,11 @@ QList ParserResRobot::parseJourneySegments(const QVari foreach (QVariant segmentData, segments) { QVariantMap segment = segmentData.toMap(); +<<<<<<< HEAD JourneyDetailResultItem* resultItem = new JourneyDetailResultItem;//FIXME will leak in QML +======= + JourneyDetailResultItem* resultItem = new JourneyDetailResultItem(results); +>>>>>>> added missed parents // Departure QVariantMap departure = segment.value("departure").toMap(); From a8d240ca126cc051c8095a56cc0d4cbe8124bad1 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 25 May 2015 01:02:20 +0200 Subject: [PATCH 28/85] not that easy there, leaving a FIXME for the next round --- src/parser/parser_resrobot.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/parser/parser_resrobot.cpp b/src/parser/parser_resrobot.cpp index 9af730ab..ba066176 100644 --- a/src/parser/parser_resrobot.cpp +++ b/src/parser/parser_resrobot.cpp @@ -537,11 +537,15 @@ QList ParserResRobot::parseJourneySegments(const QVari foreach (QVariant segmentData, segments) { QVariantMap segment = segmentData.toMap(); +<<<<<<< HEAD <<<<<<< HEAD JourneyDetailResultItem* resultItem = new JourneyDetailResultItem;//FIXME will leak in QML ======= JourneyDetailResultItem* resultItem = new JourneyDetailResultItem(results); >>>>>>> added missed parents +======= + JourneyDetailResultItem* resultItem = new JourneyDetailResultItem;//FIXME will leak in QML +>>>>>>> not that easy there, leaving a FIXME for the next round // Departure QVariantMap departure = segment.value("departure").toMap(); From 253877b1de62720d77c2cd2aac61ef5aadb52132 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Thu, 28 May 2015 02:13:38 +0200 Subject: [PATCH 29/85] fixing leaks --- src/parser/parser_hafasxml.cpp | 4 ++++ src/parser/parser_hafasxml.h | 1 + 2 files changed, 5 insertions(+) diff --git a/src/parser/parser_hafasxml.cpp b/src/parser/parser_hafasxml.cpp index ec0ec1cf..35cc5123 100644 --- a/src/parser/parser_hafasxml.cpp +++ b/src/parser/parser_hafasxml.cpp @@ -539,7 +539,11 @@ void ParserHafasXml::searchJourney(const Station &departureStation, const Statio currentRequestState = FahrplanNS::searchJourneyRequest; hafasContext.seqNr = ""; +<<<<<<< HEAD clearJourney(); +======= + cleanupJourney(); +>>>>>>> fixing leaks QString trainrestr = getTrainRestrictionsCodes(trainrestrictions); diff --git a/src/parser/parser_hafasxml.h b/src/parser/parser_hafasxml.h index 513d206a..d6e2ca9f 100644 --- a/src/parser/parser_hafasxml.h +++ b/src/parser/parser_hafasxml.h @@ -92,6 +92,7 @@ public slots: void parseSearchLaterJourney(QNetworkReply *networkReply); void parseSearchEarlierJourney(QNetworkReply *networkReply); void parseJourneyDetails(QNetworkReply *networkReply); + void cleanupJourney(); virtual QString getTrainRestrictionsCodes(int trainrestrictions); JourneyResultList *lastJourneyResultList; From bb6c564b4f79932a873a365d83c41bb19fbb025a Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Sun, 31 May 2015 23:27:52 +0200 Subject: [PATCH 30/85] clearJourney() is a more proper name --- src/parser/parser_hafasxml.cpp | 4 ---- src/parser/parser_hafasxml.h | 1 - 2 files changed, 5 deletions(-) diff --git a/src/parser/parser_hafasxml.cpp b/src/parser/parser_hafasxml.cpp index 35cc5123..ec0ec1cf 100644 --- a/src/parser/parser_hafasxml.cpp +++ b/src/parser/parser_hafasxml.cpp @@ -539,11 +539,7 @@ void ParserHafasXml::searchJourney(const Station &departureStation, const Statio currentRequestState = FahrplanNS::searchJourneyRequest; hafasContext.seqNr = ""; -<<<<<<< HEAD clearJourney(); -======= - cleanupJourney(); ->>>>>>> fixing leaks QString trainrestr = getTrainRestrictionsCodes(trainrestrictions); diff --git a/src/parser/parser_hafasxml.h b/src/parser/parser_hafasxml.h index d6e2ca9f..513d206a 100644 --- a/src/parser/parser_hafasxml.h +++ b/src/parser/parser_hafasxml.h @@ -92,7 +92,6 @@ public slots: void parseSearchLaterJourney(QNetworkReply *networkReply); void parseSearchEarlierJourney(QNetworkReply *networkReply); void parseJourneyDetails(QNetworkReply *networkReply); - void cleanupJourney(); virtual QString getTrainRestrictionsCodes(int trainrestrictions); JourneyResultList *lastJourneyResultList; From c766afa15da57a1ac747ca6c250ee81681dcff30 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 1 Jun 2015 00:05:17 +0200 Subject: [PATCH 31/85] fixing ParserXmlVasttrafikSe memory leaks --- src/parser/parser_xmlvasttrafikse.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/parser/parser_xmlvasttrafikse.cpp b/src/parser/parser_xmlvasttrafikse.cpp index 02e682b1..abf75ab0 100644 --- a/src/parser/parser_xmlvasttrafikse.cpp +++ b/src/parser/parser_xmlvasttrafikse.cpp @@ -325,6 +325,15 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) clearJourney(); lastJourneyResultList = new JourneyResultList(this); +<<<<<<< HEAD +======= + + for (QHash::Iterator it = cachedJourneyDetails.begin(); it != cachedJourneyDetails.end();) { + JourneyDetailResultList *jdrl = it.value(); + it = cachedJourneyDetails.erase(it); + delete jdrl; + } +>>>>>>> fixing ParserXmlVasttrafikSe memory leaks /// Use fallback values for empty results (i.e. no connections found) lastJourneyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); From d2be2130a61725849e3f7fe8091a32cc86946a68 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 1 Jun 2015 00:28:42 +0200 Subject: [PATCH 32/85] one more small fix to vasttrafikse --- src/parser/parser_xmlvasttrafikse.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/parser/parser_xmlvasttrafikse.cpp b/src/parser/parser_xmlvasttrafikse.cpp index abf75ab0..02e682b1 100644 --- a/src/parser/parser_xmlvasttrafikse.cpp +++ b/src/parser/parser_xmlvasttrafikse.cpp @@ -325,15 +325,6 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) clearJourney(); lastJourneyResultList = new JourneyResultList(this); -<<<<<<< HEAD -======= - - for (QHash::Iterator it = cachedJourneyDetails.begin(); it != cachedJourneyDetails.end();) { - JourneyDetailResultList *jdrl = it.value(); - it = cachedJourneyDetails.erase(it); - delete jdrl; - } ->>>>>>> fixing ParserXmlVasttrafikSe memory leaks /// Use fallback values for empty results (i.e. no connections found) lastJourneyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); From adff4e2248acd6766a486279b16b12c4fd2ba6f5 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Thu, 21 May 2015 01:09:17 +0200 Subject: [PATCH 33/85] Fix for QObject* ownership bugs Due to returning QObject* in calls to C++ objects from QML (e.g. getItem(i)), those objects were changing ownership to QML and were subject to gc. That could've been noticed during switching between journey results and journey details results (instantly switch back and forth to create enough garbage). `var item = result.getItem(i);` `item` would be null after some time. So it was ending up in page showing loader and not doing anything or in a bit more rare cases with segfault. --- rpm/harbour-fahrplan2.yaml | 2 ++ src/parser/parser_definitions.cpp | 9 +++++++++ src/parser/parser_definitions.h | 2 ++ src/parser/parser_efa.cpp | 4 ++-- src/parser/parser_hafasbinary.cpp | 4 ++-- src/parser/parser_hafasxml.cpp | 4 ++-- src/parser/parser_xmlvasttrafikse.cpp | 4 ++-- 7 files changed, 21 insertions(+), 8 deletions(-) diff --git a/rpm/harbour-fahrplan2.yaml b/rpm/harbour-fahrplan2.yaml index 788633dd..6398ff4b 100644 --- a/rpm/harbour-fahrplan2.yaml +++ b/rpm/harbour-fahrplan2.yaml @@ -15,8 +15,10 @@ PkgConfigBR: - Qt5Quick - Qt5Qml - Qt5Core +- sailfishapp Requires: - sailfishsilica-qt5 >= 0.10.9 +- qt5-qtdeclarative-import-positioning Files: - '%{_datadir}/icons/hicolor/86x86/apps/%{name}.png' - '%{_datadir}/applications/%{name}.desktop' diff --git a/src/parser/parser_definitions.cpp b/src/parser/parser_definitions.cpp index 13363e72..970fcce5 100644 --- a/src/parser/parser_definitions.cpp +++ b/src/parser/parser_definitions.cpp @@ -127,6 +127,10 @@ void JourneyResultList::setTimeInfo(const QString &timeInfo) } //------------- JourneyResultItem +JourneyResultItem::JourneyResultItem(QObject *parent) : QObject(parent) +{ + +} QString JourneyResultItem::id() const { @@ -327,6 +331,11 @@ void JourneyDetailResultList::setDuration(const QString &duration) //------------- JourneyDetailResultItem +JourneyDetailResultItem::JourneyDetailResultItem(QObject *parent) : QObject(parent) +{ + +} + QString JourneyDetailResultItem::departureStation() const { return m_departureStation; diff --git a/src/parser/parser_definitions.h b/src/parser/parser_definitions.h index 7587c1ab..94278a1e 100644 --- a/src/parser/parser_definitions.h +++ b/src/parser/parser_definitions.h @@ -95,6 +95,7 @@ class JourneyResultItem : public QObject Q_PROPERTY(QString internalData2 READ internalData2 WRITE setInternalData2) public: + explicit JourneyResultItem(QObject * parent = 0); QString id() const; void setId(const QString &); QDate date() const; @@ -176,6 +177,7 @@ class JourneyDetailResultItem : public QObject Q_PROPERTY(QString internalData1 READ internalData1 WRITE setInternalData1) Q_PROPERTY(QString internalData2 READ internalData2 WRITE setInternalData2) public: + explicit JourneyDetailResultItem(QObject * parent = 0); QString departureStation() const; void setDepartureStation(const QString &); QString departureInfo() const; diff --git a/src/parser/parser_efa.cpp b/src/parser/parser_efa.cpp index d934be35..0ed6c2b5 100755 --- a/src/parser/parser_efa.cpp +++ b/src/parser/parser_efa.cpp @@ -542,7 +542,7 @@ void ParserEFA::parseSearchJourney(QNetworkReply *networkReply) info = tr("Guaranteed connection"); } motNameList.append(motName); - JourneyDetailResultItem *jdrItem = new JourneyDetailResultItem(); + JourneyDetailResultItem *jdrItem = new JourneyDetailResultItem(detailsList); jdrItem->setTrain(motName); jdrItem->setInfo(info); jdrItem->setDirection(motElement.attribute("destination")); @@ -580,7 +580,7 @@ void ParserEFA::parseSearchJourney(QNetworkReply *networkReply) detailsList->setDepartureDateTime(departureDateTime); cachedJourneyDetailsEfa[id] = detailsList; - JourneyResultItem *item = new JourneyResultItem(); + JourneyResultItem *item = new JourneyResultItem(lastJourneyResultList); item->setDate(departureDateTime.date()); item->setId(id); item->setTransfers(changes); diff --git a/src/parser/parser_hafasbinary.cpp b/src/parser/parser_hafasbinary.cpp index b66dcc47..e1bc1ac6 100644 --- a/src/parser/parser_hafasbinary.cpp +++ b/src/parser/parser_hafasbinary.cpp @@ -328,7 +328,7 @@ void ParserHafasBinary::parseSearchJourney(QNetworkReply *networkReply) for (int iPart = 0; iPart < numParts; iPart++) { - JourneyDetailResultItem *inlineItem = new JourneyDetailResultItem(); + JourneyDetailResultItem *inlineItem = new JourneyDetailResultItem(inlineResults); hafasData.device()->seek(0x4a + partsOffset + iPart * 20); @@ -571,7 +571,7 @@ void ParserHafasBinary::parseSearchJourney(QNetworkReply *networkReply) lineNames.removeDuplicates(); - JourneyResultItem *item = new JourneyResultItem(); + JourneyResultItem *item = new JourneyResultItem(lastJourneyResultList); item->setDate(journeyDate); item->setId(connectionId); item->setTransfers(QString::number(numChanges)); diff --git a/src/parser/parser_hafasxml.cpp b/src/parser/parser_hafasxml.cpp index ee129b3c..b110c62b 100644 --- a/src/parser/parser_hafasxml.cpp +++ b/src/parser/parser_hafasxml.cpp @@ -656,7 +656,7 @@ void ParserHafasXml::parseSearchJourney(QNetworkReply *networkReply) const QDomNodeList connections = doc.elementsByTagName("Connection"); for (int i = 0; i < connections.count(); ++i) { - JourneyResultItem *item = new JourneyResultItem(); + JourneyResultItem *item = new JourneyResultItem(lastJourneyResultList); item->setId(connections.at(i).toElement().attribute("id").trimmed()); QDomElement overview = connections.at(i).firstChildElement("Overview"); @@ -846,7 +846,7 @@ JourneyDetailResultList* ParserHafasXml::internalParseJourneyDetails(const QDomE const QDomNodeList sections = connection.elementsByTagName("ConSection"); for (int i = 0; i < sections.count(); ++i) { - JourneyDetailResultItem *item = new JourneyDetailResultItem(); + JourneyDetailResultItem *item = new JourneyDetailResultItem(results); const QDomNode section = sections.at(i); QDomElement stop; diff --git a/src/parser/parser_xmlvasttrafikse.cpp b/src/parser/parser_xmlvasttrafikse.cpp index 75534115..f702413c 100644 --- a/src/parser/parser_xmlvasttrafikse.cpp +++ b/src/parser/parser_xmlvasttrafikse.cpp @@ -329,7 +329,7 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) if (doc.setContent(xmlRawtext, false)) { QDomNodeList tripNodeList = doc.elementsByTagName("Trip"); for (unsigned int i = 0; i < tripNodeList.length(); ++i) { - JourneyResultItem *jritem = new JourneyResultItem(); + JourneyResultItem *jritem = new JourneyResultItem(journeyResultList); JourneyDetailResultList *detailsList = new JourneyDetailResultList(); /// Set default values for journey's start and end time @@ -367,7 +367,7 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) trainTypes.append(i18nConnectionType(getAttribute(legNode, "name"))); } - JourneyDetailResultItem *jdrItem = new JourneyDetailResultItem(); + JourneyDetailResultItem *jdrItem = new JourneyDetailResultItem(detailsList); jdrItem->setDepartureStation(getAttribute(originNode, "name")); const QString depTrack = getAttribute(originNode, "track"); jdrItem->setDepartureInfo(depTrack.isEmpty() ? QChar(0x2014) : tr("Track %1").arg(depTrack)); From b3a2b76818bc7de3cecd2e051c911c5c08ea9866 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 25 May 2015 00:46:48 +0200 Subject: [PATCH 34/85] added missed parents --- src/parser/parser_ninetwo.cpp | 4 ++-- src/parser/parser_resrobot.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/parser/parser_ninetwo.cpp b/src/parser/parser_ninetwo.cpp index 0386775d..4dd83937 100644 --- a/src/parser/parser_ninetwo.cpp +++ b/src/parser/parser_ninetwo.cpp @@ -345,7 +345,7 @@ void ParserNinetwo::parseSearchJourney(QNetworkReply *networkReply) for (i = journeys.constBegin(); i != journeys.constEnd(); ++i) { QVariantMap journey = i->toMap(); parseJourneyOption(journey); - JourneyResultItem* item = new JourneyResultItem; + JourneyResultItem* item = new JourneyResultItem(result); arrival = QDateTime::fromString(journey.value("arrival").toString(), "yyyy-MM-ddTHH:mm"); departure = QDateTime::fromString(journey.value("departure").toString(), "yyyy-MM-ddTHH:mm"); @@ -424,7 +424,7 @@ void ParserNinetwo::parseJourneyOption(const QVariantMap &object) for(int i = 0; i < legs.count(); i++) { QVariantMap leg = legs.at(i).toMap(); - JourneyDetailResultItem* resultItem = new JourneyDetailResultItem; + JourneyDetailResultItem* resultItem = new JourneyDetailResultItem(result); QVariantList stops = leg.value("stops").toList(); diff --git a/src/parser/parser_resrobot.cpp b/src/parser/parser_resrobot.cpp index c0fbc0cb..40e97a56 100644 --- a/src/parser/parser_resrobot.cpp +++ b/src/parser/parser_resrobot.cpp @@ -479,7 +479,7 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) else if (arrDayDiff < 0) arrTime += QString::number(arrDayDiff); - JourneyResultItem* journey = new JourneyResultItem; + JourneyResultItem* journey = new JourneyResultItem(result); journey->setId(journeyID); journey->setDate(segments.first()->departureDateTime().date()); journey->setDepartureTime(depTime); @@ -523,7 +523,7 @@ QList ParserResRobot::parseJourneySegments(const QVari foreach (QVariant segmentData, segments) { QVariantMap segment = segmentData.toMap(); - JourneyDetailResultItem* resultItem = new JourneyDetailResultItem; + JourneyDetailResultItem* resultItem = new JourneyDetailResultItem(results); // Departure QVariantMap departure = segment.value("departure").toMap(); From 98201ac41aaab6b30288c0f01bac1e3d3956de41 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 25 May 2015 01:02:20 +0200 Subject: [PATCH 35/85] not that easy there, leaving a FIXME for the next round --- src/parser/parser_resrobot.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/parser/parser_resrobot.cpp b/src/parser/parser_resrobot.cpp index 40e97a56..f2b1b1ab 100644 --- a/src/parser/parser_resrobot.cpp +++ b/src/parser/parser_resrobot.cpp @@ -479,7 +479,7 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) else if (arrDayDiff < 0) arrTime += QString::number(arrDayDiff); - JourneyResultItem* journey = new JourneyResultItem(result); + JourneyResultItem* journey = new JourneyResultItem(journeyList); journey->setId(journeyID); journey->setDate(segments.first()->departureDateTime().date()); journey->setDepartureTime(depTime); @@ -523,7 +523,7 @@ QList ParserResRobot::parseJourneySegments(const QVari foreach (QVariant segmentData, segments) { QVariantMap segment = segmentData.toMap(); - JourneyDetailResultItem* resultItem = new JourneyDetailResultItem(results); + JourneyDetailResultItem* resultItem = new JourneyDetailResultItem;//FIXME will leak in QML // Departure QVariantMap departure = segment.value("departure").toMap(); From 35db43b905ff61977e92c6e18c9bf67e1d2cafc0 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Thu, 28 May 2015 02:12:07 +0200 Subject: [PATCH 36/85] added missing destructors --- src/parser/parser_definitions.cpp | 20 ++++++++++++++++++++ src/parser/parser_definitions.h | 4 ++++ 2 files changed, 24 insertions(+) diff --git a/src/parser/parser_definitions.cpp b/src/parser/parser_definitions.cpp index 970fcce5..8976bf51 100644 --- a/src/parser/parser_definitions.cpp +++ b/src/parser/parser_definitions.cpp @@ -71,6 +71,16 @@ TimetableEntry::TimetableEntry() //------------- JourneyResultList +JourneyResultList::JourneyResultList(QObject * parent) : QObject(parent) +{ + +} + +JourneyResultList::~JourneyResultList() +{ + qDeleteAll(m_items); +} + qreal JourneyResultList::itemcount() { return m_items.count(); @@ -234,6 +244,16 @@ void JourneyResultItem::setInternalData2(const QString &internalData2) //------------- JourneyDetailResultList +JourneyDetailResultList::JourneyDetailResultList(QObject * parent) : QObject(parent) +{ + +} + +JourneyDetailResultList::~JourneyDetailResultList() +{ + qDeleteAll(m_items); +} + QString JourneyDetailResultList::id() const { return m_id; diff --git a/src/parser/parser_definitions.h b/src/parser/parser_definitions.h index 94278a1e..e15d1620 100644 --- a/src/parser/parser_definitions.h +++ b/src/parser/parser_definitions.h @@ -141,6 +141,8 @@ class JourneyResultList : public QObject public slots: JourneyResultItem *getItem(int); public: + explicit JourneyResultList(QObject * parent = 0); + virtual ~JourneyResultList(); void appendItem(JourneyResultItem *item); qreal itemcount(); QString departureStation() const; @@ -230,6 +232,8 @@ class JourneyDetailResultList : public QObject public slots: JourneyDetailResultItem *getItem(int); public: + explicit JourneyDetailResultList(QObject * parent = 0); + virtual ~JourneyDetailResultList(); void appendItem(JourneyDetailResultItem *item); qreal itemcount(); QString id() const; From bfdeedc67775dc04cb4efb74bebf825c1a32467a Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Thu, 28 May 2015 02:13:38 +0200 Subject: [PATCH 37/85] fixing leaks --- src/parser/parser_hafasbinary.cpp | 9 +++++---- src/parser/parser_hafasxml.cpp | 24 ++++++++++++++++++++++-- src/parser/parser_hafasxml.h | 2 ++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/parser/parser_hafasbinary.cpp b/src/parser/parser_hafasbinary.cpp index e1bc1ac6..5f790ead 100644 --- a/src/parser/parser_hafasbinary.cpp +++ b/src/parser/parser_hafasbinary.cpp @@ -43,7 +43,8 @@ void ParserHafasBinary::searchJourney(const Station &departureStation, const Sta currentRequestState = FahrplanNS::searchJourneyRequest; hafasContext.seqNr = ""; - lastJourneyResultList = NULL; + + cleanupJourney(); QString trainrestr = getTrainRestrictionsCodes(trainrestrictions); @@ -85,8 +86,8 @@ void ParserHafasBinary::searchJourney(const Station &departureStation, const Sta void ParserHafasBinary::parseSearchJourney(QNetworkReply *networkReply) { - lastJourneyResultList = new JourneyResultList(); - journeyDetailInlineData.clear(); + lastJourneyResultList = new JourneyResultList(this); + stringCache.clear(); QByteArray tmpBuffer = networkReply->readAll(); @@ -324,7 +325,7 @@ void ParserHafasBinary::parseSearchJourney(QNetworkReply *networkReply) qDebug()<<"conId"<readAll())) diff --git a/src/parser/parser_hafasxml.h b/src/parser/parser_hafasxml.h index aee85971..6ad4a46e 100644 --- a/src/parser/parser_hafasxml.h +++ b/src/parser/parser_hafasxml.h @@ -57,6 +57,7 @@ class ParserHafasXml : public ParserAbstract Q_OBJECT public: explicit ParserHafasXml(QObject *parent = 0); + virtual ~ParserHafasXml(); static QString getName() { return "HafasXML"; } virtual QString name() { return getName(); } virtual QString shortName() { return getName(); } @@ -90,6 +91,7 @@ public slots: void parseSearchLaterJourney(QNetworkReply *networkReply); void parseSearchEarlierJourney(QNetworkReply *networkReply); void parseJourneyDetails(QNetworkReply *networkReply); + void cleanupJourney(); virtual QString getTrainRestrictionsCodes(int trainrestrictions); JourneyResultList *lastJourneyResultList; From 02eff80baa9674fe7ac9d60fcaa55477c55e0b2e Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Thu, 28 May 2015 02:15:47 +0200 Subject: [PATCH 38/85] ownership, concurrency and and destructor for parser backend manager and thread --- src/fahrplan_backend_manager.cpp | 10 +++++++++- src/fahrplan_backend_manager.h | 1 + src/fahrplan_parser_thread.h | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/fahrplan_backend_manager.cpp b/src/fahrplan_backend_manager.cpp index 732357bb..aed57f55 100644 --- a/src/fahrplan_backend_manager.cpp +++ b/src/fahrplan_backend_manager.cpp @@ -26,6 +26,14 @@ FahrplanBackendManager::FahrplanBackendManager(int defaultParser, QObject *paren currentParserIndex = defaultParser; } +FahrplanBackendManager::~FahrplanBackendManager() +{ + if (m_parser) { + // Parser object will be autodeleted after the thread quits. + m_parser->quit(); + } +} + QStringList FahrplanBackendManager::getParserList() { QStringList result; @@ -68,7 +76,7 @@ void FahrplanBackendManager::setParser(int index) m_parser->quit(); } - m_parser = new FahrplanParserThread(); + m_parser = new FahrplanParserThread(this); m_parser->init(index); emit parserChanged(m_parser->name(), currentParserIndex); diff --git a/src/fahrplan_backend_manager.h b/src/fahrplan_backend_manager.h index fc7797b9..1672cc8f 100644 --- a/src/fahrplan_backend_manager.h +++ b/src/fahrplan_backend_manager.h @@ -28,6 +28,7 @@ class FahrplanBackendManager : public QObject public: explicit FahrplanBackendManager(int defaultParser, QObject *parent = 0); + virtual ~FahrplanBackendManager(); QStringList getParserList(); void setParser(int index); FahrplanParserThread *getParser(); diff --git a/src/fahrplan_parser_thread.h b/src/fahrplan_parser_thread.h index 8072f1ee..90a3d758 100644 --- a/src/fahrplan_parser_thread.h +++ b/src/fahrplan_parser_thread.h @@ -89,7 +89,7 @@ public slots: void run(); private: - bool m_ready; + volatile bool m_ready; int i_parser; QStringList m_trainrestrictions; From 95604c59ebcb5bf9e338ba5e8f44e8fe1d9b841e Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Sun, 31 May 2015 23:27:52 +0200 Subject: [PATCH 39/85] clearJourney() is a more proper name --- src/parser/parser_hafasbinary.cpp | 2 +- src/parser/parser_hafasxml.cpp | 6 +++--- src/parser/parser_hafasxml.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/parser/parser_hafasbinary.cpp b/src/parser/parser_hafasbinary.cpp index 5f790ead..bce5fcde 100644 --- a/src/parser/parser_hafasbinary.cpp +++ b/src/parser/parser_hafasbinary.cpp @@ -44,7 +44,7 @@ void ParserHafasBinary::searchJourney(const Station &departureStation, const Sta currentRequestState = FahrplanNS::searchJourneyRequest; hafasContext.seqNr = ""; - cleanupJourney(); + clearJourney(); QString trainrestr = getTrainRestrictionsCodes(trainrestrictions); diff --git a/src/parser/parser_hafasxml.cpp b/src/parser/parser_hafasxml.cpp index f89f7c85..ec0ec1cf 100644 --- a/src/parser/parser_hafasxml.cpp +++ b/src/parser/parser_hafasxml.cpp @@ -54,10 +54,10 @@ ParserHafasXml::ParserHafasXml(QObject *parent) : ParserHafasXml::~ParserHafasXml() { - cleanupJourney(); + clearJourney(); } -void ParserHafasXml::cleanupJourney() +void ParserHafasXml::clearJourney() { if (lastJourneyResultList) { delete lastJourneyResultList; @@ -539,7 +539,7 @@ void ParserHafasXml::searchJourney(const Station &departureStation, const Statio currentRequestState = FahrplanNS::searchJourneyRequest; hafasContext.seqNr = ""; - cleanupJourney(); + clearJourney(); QString trainrestr = getTrainRestrictionsCodes(trainrestrictions); diff --git a/src/parser/parser_hafasxml.h b/src/parser/parser_hafasxml.h index 6ad4a46e..513d206a 100644 --- a/src/parser/parser_hafasxml.h +++ b/src/parser/parser_hafasxml.h @@ -75,6 +75,7 @@ public slots: bool supportsTimeTable(); bool supportsTimeTableDirection(); QStringList getTrainRestrictions(); + virtual void clearJourney(); protected: QString baseXmlUrl; @@ -91,7 +92,6 @@ public slots: void parseSearchLaterJourney(QNetworkReply *networkReply); void parseSearchEarlierJourney(QNetworkReply *networkReply); void parseJourneyDetails(QNetworkReply *networkReply); - void cleanupJourney(); virtual QString getTrainRestrictionsCodes(int trainrestrictions); JourneyResultList *lastJourneyResultList; From 2cea328de1c363c16f8b56c2140ca9342af8c23a Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Sun, 31 May 2015 23:29:41 +0200 Subject: [PATCH 40/85] adding clearJourney to EFA parser --- src/parser/parser_efa.cpp | 15 +++++++++++++++ src/parser/parser_efa.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/src/parser/parser_efa.cpp b/src/parser/parser_efa.cpp index 0ed6c2b5..3fe3a3a4 100755 --- a/src/parser/parser_efa.cpp +++ b/src/parser/parser_efa.cpp @@ -108,6 +108,19 @@ ParserEFA::ParserEFA(QObject *parent) : m_timeTableForStationParameters.isValid = false; } +ParserEFA::~ParserEFA() +{ + clearJourney(); +} + +void ParserEFA::clearJourney() +{ + if (lastJourneyResultList) { + delete lastJourneyResultList; + lastJourneyResultList = NULL; + } +} + bool ParserEFA::supportsGps() { return true; @@ -504,6 +517,8 @@ void ParserEFA::searchJourney(const Station &departureStation, const Station &vi void ParserEFA::parseSearchJourney(QNetworkReply *networkReply) { qDebug() << "ParserEFA::parseSearchJourney(QNetworkReply *networkReply)"; + clearJourney(); + lastJourneyResultList = new JourneyResultList(); for (QHash::Iterator it = cachedJourneyDetailsEfa.begin(); it != cachedJourneyDetailsEfa.end();) { diff --git a/src/parser/parser_efa.h b/src/parser/parser_efa.h index 1ce9573b..c31e3cfc 100755 --- a/src/parser/parser_efa.h +++ b/src/parser/parser_efa.h @@ -29,6 +29,7 @@ class ParserEFA : public ParserAbstract Q_OBJECT public: explicit ParserEFA(QObject *parent = 0); + virtual ~ParserEFA(); static QString getName() { return "EFA"; } virtual QString name() { return getName(); } virtual QString shortName() { return getName(); } @@ -47,6 +48,7 @@ public slots: bool supportsTimeTableDirection(); void checkForError(QDomDocument *serverReplyDomDoc); QStringList getTrainRestrictions(); + virtual void clearJourney(); protected: QString baseRestUrl; From bc82fa077660543b778b3b5a35ad1ff53b552696 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 1 Jun 2015 00:05:17 +0200 Subject: [PATCH 41/85] fixing ParserXmlVasttrafikSe memory leaks --- src/parser/parser_xmlvasttrafikse.cpp | 69 ++++++++++++++++----------- src/parser/parser_xmlvasttrafikse.h | 4 ++ 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/src/parser/parser_xmlvasttrafikse.cpp b/src/parser/parser_xmlvasttrafikse.cpp index f702413c..b99e7d58 100644 --- a/src/parser/parser_xmlvasttrafikse.cpp +++ b/src/parser/parser_xmlvasttrafikse.cpp @@ -46,6 +46,18 @@ ParserXmlVasttrafikSe::ParserXmlVasttrafikSe(QObject *parent) m_timeTableForStationParameters.isValid = false; } +ParserXmlVasttrafikSe::~ParserXmlVasttrafikSe() +{ + clearJourney(); +} + +void ParserXmlVasttrafikSe::clearJourney() +{ + if (lastJourneyResultList) { + delete lastJourneyResultList; + lastJourneyResultList = NULL; + } +} void ParserXmlVasttrafikSe::getTimeTableForStation(const Station ¤tStation, const Station &, const QDateTime &dateTime, Mode mode, int) { @@ -305,7 +317,8 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) { qDebug() << "ParserXmlVasttrafikSe::parseSearchJourney(networkReply.url()=" << networkReply->url().toString() << ")"; - JourneyResultList *journeyResultList = new JourneyResultList(); + clearJourney(); + lastJourneyResultList = new JourneyResultList(this); for (QHash::Iterator it = cachedJourneyDetails.begin(); it != cachedJourneyDetails.end();) { JourneyDetailResultList *jdrl = it.value(); @@ -314,11 +327,11 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) } /// Use fallback values for empty results (i.e. no connections found) - journeyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); - journeyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); - journeyResultList->setArrivalStation(m_searchJourneyParameters.arrivalStation.name); + lastJourneyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); + lastJourneyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); + lastJourneyResultList->setArrivalStation(m_searchJourneyParameters.arrivalStation.name); //: DATE, TIME - journeyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(m_searchJourneyParameters.dateTime.date().toString(Qt::DefaultLocaleShortDate)).arg(m_searchJourneyParameters.dateTime.time().toString(Qt::DefaultLocaleShortDate))); + lastJourneyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(m_searchJourneyParameters.dateTime.date().toString(Qt::DefaultLocaleShortDate)).arg(m_searchJourneyParameters.dateTime.time().toString(Qt::DefaultLocaleShortDate))); m_earliestArrival = m_latestResultDeparture = QDateTime(); @@ -329,8 +342,8 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) if (doc.setContent(xmlRawtext, false)) { QDomNodeList tripNodeList = doc.elementsByTagName("Trip"); for (unsigned int i = 0; i < tripNodeList.length(); ++i) { - JourneyResultItem *jritem = new JourneyResultItem(journeyResultList); - JourneyDetailResultList *detailsList = new JourneyDetailResultList(); + JourneyResultItem *jritem = new JourneyResultItem(lastJourneyResultList); + JourneyDetailResultList *detailsList = new JourneyDetailResultList(this); /// Set default values for journey's start and end time QDateTime journeyStart = QDateTime::currentDateTime(); @@ -351,15 +364,15 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) journeyStart.setTime(time); if (i == 0) { const QDate date = QDate::fromString(getAttribute(originNode, "date"), QLatin1String("yyyy-MM-dd")); - journeyResultList->setDepartureStation(getAttribute(originNode, "name")); + lastJourneyResultList->setDepartureStation(getAttribute(originNode, "name")); //: DATE, TIME - journeyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(date.toString(Qt::DefaultLocaleShortDate)).arg(time.toString(Qt::DefaultLocaleShortDate))); + lastJourneyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(date.toString(Qt::DefaultLocaleShortDate)).arg(time.toString(Qt::DefaultLocaleShortDate))); } } if (j == legNodeList.length() - 1) { journeyEnd.setTime(QTime::fromString(getAttribute(destinationNode, "time"), "hh:mm")); if (i == 0) - journeyResultList->setArrivalStation(getAttribute(destinationNode, "name")); + lastJourneyResultList->setArrivalStation(getAttribute(destinationNode, "name")); } if (getAttribute(legNode, "type") != QLatin1String("WALK") || getAttribute(originNode, "name") != getAttribute(destinationNode, "name")) { @@ -441,14 +454,14 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) else if (tripRtStatus == TRIP_RTDATA_ONTIME) jritem->setMiscInfo(tr("on time")); - journeyResultList->appendItem(jritem); + lastJourneyResultList->appendItem(jritem); const QString id = QString::number(i); jritem->setId(id); detailsList->setId(id); - detailsList->setDepartureStation(journeyResultList->departureStation()); - detailsList->setViaStation(journeyResultList->viaStation()); - detailsList->setArrivalStation(journeyResultList->arrivalStation()); + detailsList->setDepartureStation(lastJourneyResultList->departureStation()); + detailsList->setViaStation(lastJourneyResultList->viaStation()); + detailsList->setArrivalStation(lastJourneyResultList->arrivalStation()); detailsList->setDuration(jritem->duration()); detailsList->setArrivalDateTime(journeyEnd); detailsList->setDepartureDateTime(journeyStart); @@ -461,7 +474,7 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) } } - emit journeyResult(journeyResultList); + emit journeyResult(lastJourneyResultList); } void ParserXmlVasttrafikSe::searchJourneyLater() @@ -469,13 +482,14 @@ void ParserXmlVasttrafikSe::searchJourneyLater() if (m_latestResultDeparture.isValid()) searchJourney(m_searchJourneyParameters.departureStation, m_searchJourneyParameters.arrivalStation, m_searchJourneyParameters.viaStation, m_latestResultDeparture, Departure, 0); else { - JourneyResultList *journeyResultList = new JourneyResultList(); - journeyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); - journeyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); - journeyResultList->setArrivalStation(m_searchJourneyParameters.arrivalStation.name); + clearJourney(); + lastJourneyResultList = new JourneyResultList(); + lastJourneyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); + lastJourneyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); + lastJourneyResultList->setArrivalStation(m_searchJourneyParameters.arrivalStation.name); //: DATE, TIME - journeyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(m_searchJourneyParameters.dateTime.date().toString(Qt::DefaultLocaleShortDate)).arg(m_searchJourneyParameters.dateTime.time().toString(Qt::DefaultLocaleShortDate))); - emit journeyResult(journeyResultList); + lastJourneyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(m_searchJourneyParameters.dateTime.date().toString(Qt::DefaultLocaleShortDate)).arg(m_searchJourneyParameters.dateTime.time().toString(Qt::DefaultLocaleShortDate))); + emit journeyResult(lastJourneyResultList); } } @@ -484,13 +498,14 @@ void ParserXmlVasttrafikSe::searchJourneyEarlier() if (m_earliestArrival.isValid()) searchJourney(m_searchJourneyParameters.departureStation, m_searchJourneyParameters.arrivalStation, m_searchJourneyParameters.viaStation, m_earliestArrival, Arrival, 0); else { - JourneyResultList *journeyResultList = new JourneyResultList(); - journeyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); - journeyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); - journeyResultList->setArrivalStation(m_searchJourneyParameters.arrivalStation.name); + clearJourney(); + lastJourneyResultList = new JourneyResultList(); + lastJourneyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); + lastJourneyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); + lastJourneyResultList->setArrivalStation(m_searchJourneyParameters.arrivalStation.name); //: DATE, TIME - journeyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(m_searchJourneyParameters.dateTime.date().toString(Qt::DefaultLocaleShortDate)).arg(m_searchJourneyParameters.dateTime.time().toString(Qt::DefaultLocaleShortDate))); - emit journeyResult(journeyResultList); + lastJourneyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(m_searchJourneyParameters.dateTime.date().toString(Qt::DefaultLocaleShortDate)).arg(m_searchJourneyParameters.dateTime.time().toString(Qt::DefaultLocaleShortDate))); + emit journeyResult(lastJourneyResultList); } } diff --git a/src/parser/parser_xmlvasttrafikse.h b/src/parser/parser_xmlvasttrafikse.h index c75004eb..238b6435 100644 --- a/src/parser/parser_xmlvasttrafikse.h +++ b/src/parser/parser_xmlvasttrafikse.h @@ -28,6 +28,7 @@ class ParserXmlVasttrafikSe : public ParserAbstract public: explicit ParserXmlVasttrafikSe(QObject *parent = 0); + virtual ~ParserXmlVasttrafikSe(); static QString getName() { return QString("%1 (vasttrafik.se)").arg(tr("Sweden")); } virtual QString name() { return getName(); } virtual QString shortName() { return "vasttrafik.se"; } @@ -46,6 +47,7 @@ public slots: virtual bool supportsTimeTableDirection(); // virtual QStringList getTrainRestrictions(); // void cancelRequest(); + virtual void clearJourney(); protected: virtual void parseStationsByName(QNetworkReply *networkReply); @@ -53,6 +55,8 @@ public slots: virtual void parseTimeTable(QNetworkReply *networkReply); virtual void parseSearchJourney(QNetworkReply *networkReply); + JourneyResultList *lastJourneyResultList; + private: static const qlonglong TRIP_RTDATA_NONE; static const qlonglong TRIP_RTDATA_ONTIME; From 9076fb0e2b92787cc0fa6a71093a379f661ed9f6 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 1 Jun 2015 00:28:42 +0200 Subject: [PATCH 42/85] one more small fix to vasttrafikse --- src/parser/parser_xmlvasttrafikse.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/parser/parser_xmlvasttrafikse.cpp b/src/parser/parser_xmlvasttrafikse.cpp index b99e7d58..02e682b1 100644 --- a/src/parser/parser_xmlvasttrafikse.cpp +++ b/src/parser/parser_xmlvasttrafikse.cpp @@ -57,6 +57,12 @@ void ParserXmlVasttrafikSe::clearJourney() delete lastJourneyResultList; lastJourneyResultList = NULL; } + + for (QHash::Iterator it = cachedJourneyDetails.begin(); it != cachedJourneyDetails.end();) { + JourneyDetailResultList *jdrl = it.value(); + it = cachedJourneyDetails.erase(it); + delete jdrl; + } } void ParserXmlVasttrafikSe::getTimeTableForStation(const Station ¤tStation, const Station &, const QDateTime &dateTime, Mode mode, int) @@ -320,12 +326,6 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) clearJourney(); lastJourneyResultList = new JourneyResultList(this); - for (QHash::Iterator it = cachedJourneyDetails.begin(); it != cachedJourneyDetails.end();) { - JourneyDetailResultList *jdrl = it.value(); - it = cachedJourneyDetails.erase(it); - delete jdrl; - } - /// Use fallback values for empty results (i.e. no connections found) lastJourneyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); lastJourneyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); From 3a009491de33573d260d85b41eca69b7569b7da6 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 1 Jun 2015 00:29:10 +0200 Subject: [PATCH 43/85] fixing ninetwo memory leaks --- src/parser/parser_ninetwo.cpp | 39 +++++++++++++++++++++++++++-------- src/parser/parser_ninetwo.h | 4 ++++ 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/parser/parser_ninetwo.cpp b/src/parser/parser_ninetwo.cpp index 4dd83937..95d88b2f 100644 --- a/src/parser/parser_ninetwo.cpp +++ b/src/parser/parser_ninetwo.cpp @@ -54,6 +54,25 @@ ParserNinetwo::ParserNinetwo(QObject *parent):ParserAbstract(parent) lastCoordinates.isValid = false; } +ParserNinetwo::~ParserNinetwo() +{ + clearJourney(); +} + +void ParserNinetwo::clearJourney() +{ + if (lastJourneyResultList) { + delete lastJourneyResultList; + lastJourneyResultList = NULL; + } + + for (QMap::Iterator it = cachedResults.begin(); it != cachedResults.end();) { + JourneyDetailResultList *jdrl = it.value(); + it = cachedResults.erase(it); + delete jdrl; + } +} + void ParserNinetwo::getTimeTableForStation(const Station ¤tStation, const Station &, const QDateTime &, @@ -336,7 +355,9 @@ void ParserNinetwo::parseSearchJourney(QNetworkReply *networkReply) QVariantList journeys = doc.value("journeys").toList(); - JourneyResultList* result=new JourneyResultList; + clearJourney(); + + lastJourneyResultList = new JourneyResultList(this); QDateTime arrival; QDateTime departure; @@ -345,7 +366,7 @@ void ParserNinetwo::parseSearchJourney(QNetworkReply *networkReply) for (i = journeys.constBegin(); i != journeys.constEnd(); ++i) { QVariantMap journey = i->toMap(); parseJourneyOption(journey); - JourneyResultItem* item = new JourneyResultItem(result); + JourneyResultItem* item = new JourneyResultItem(lastJourneyResultList); arrival = QDateTime::fromString(journey.value("arrival").toString(), "yyyy-MM-ddTHH:mm"); departure = QDateTime::fromString(journey.value("departure").toString(), "yyyy-MM-ddTHH:mm"); @@ -376,17 +397,17 @@ void ParserNinetwo::parseSearchJourney(QNetworkReply *networkReply) int minutes = departure.secsTo(arrival)/60; item->setDuration(QString("%1:%2").arg(minutes/60).arg(minutes%60,2,10,QChar('0'))); item->setId(journey.value("id").toString()); - result->appendItem(item); + lastJourneyResultList ->appendItem(item); //Set result metadata based on first result - if (result->itemcount() == 1) { - result->setTimeInfo(arrival.date().toString()); - result->setDepartureStation(cachedResults[item->id()]->departureStation()); - result->setArrivalStation(cachedResults[item->id()]->arrivalStation()); + if (lastJourneyResultList ->itemcount() == 1) { + lastJourneyResultList ->setTimeInfo(arrival.date().toString()); + lastJourneyResultList ->setDepartureStation(cachedResults[item->id()]->departureStation()); + lastJourneyResultList ->setArrivalStation(cachedResults[item->id()]->arrivalStation()); } } lastsearch.lastOption=departure; - emit journeyResult(result); + emit journeyResult(lastJourneyResultList ); } void ParserNinetwo::parseSearchLaterJourney(QNetworkReply *) @@ -406,7 +427,7 @@ void ParserNinetwo::parseJourneyDetails(QNetworkReply *) void ParserNinetwo::parseJourneyOption(const QVariantMap &object) { - JourneyDetailResultList* result = new JourneyDetailResultList; + JourneyDetailResultList* result = new JourneyDetailResultList(this); QString id = object.value("id").toString(); QVariantList legs = object.value("legs").toList(); diff --git a/src/parser/parser_ninetwo.h b/src/parser/parser_ninetwo.h index a58c95e9..e142004f 100644 --- a/src/parser/parser_ninetwo.h +++ b/src/parser/parser_ninetwo.h @@ -60,6 +60,7 @@ class ParserNinetwo : public ParserAbstract public: ParserNinetwo(QObject* parent = 0); + virtual ~ParserNinetwo(); // ParserAbstract interface public: @@ -80,6 +81,7 @@ public slots: bool supportsTimeTable() { return true; } bool supportsTimeTableDirection() { return false; } QStringList getTrainRestrictions(); + virtual void clearJourney(); protected: void parseTimeTable(QNetworkReply *networkReply); @@ -91,6 +93,8 @@ public slots: void parseJourneyDetails(QNetworkReply *networkReply); QMap cachedResults; + JourneyResultList *lastJourneyResultList; + private: void parseJourneyOption(const QVariantMap &object); }; From 420764f2ed3aa91d2d9f2b61651f610032af0fe3 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 1 Jun 2015 00:29:31 +0200 Subject: [PATCH 44/85] fixing resrobot memory leaks --- src/parser/parser_resrobot.cpp | 30 ++++++++++++++++++++++-------- src/parser/parser_resrobot.h | 4 ++++ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/parser/parser_resrobot.cpp b/src/parser/parser_resrobot.cpp index f2b1b1ab..d097fbb5 100644 --- a/src/parser/parser_resrobot.cpp +++ b/src/parser/parser_resrobot.cpp @@ -87,6 +87,19 @@ ParserResRobot::ParserResRobot(QObject *parent) : transportModeStrings[QString::fromUtf8("Γ–vriga tΓ₯g")] = tr("Other train"); } +ParserResRobot::~ParserResRobot() +{ + clearJourney(); +} + +void ParserResRobot::clearJourney() +{ + if (lastJourneyResultList) { + delete lastJourneyResultList; + lastJourneyResultList = NULL; + } +} + bool ParserResRobot::supportsGps() { return true; @@ -430,7 +443,8 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) cachedResults.clear(); - JourneyResultList *journeyList = new JourneyResultList(); + clearJourney(); + lastJourneyResultList = new JourneyResultList(this); int journeyCounter = 0; foreach (QVariant journeyData, journeyListData) { @@ -454,7 +468,7 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) if (transportModes.count() == 0 && segments.count() == 1) transportModes.append(segments.first()->train()); - JourneyDetailResultList* journeyDetails = new JourneyDetailResultList; + JourneyDetailResultList* journeyDetails = new JourneyDetailResultList(this); foreach (JourneyDetailResultItem* segment, segments) journeyDetails->appendItem(segment); journeyDetails->setId(journeyID); @@ -479,7 +493,7 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) else if (arrDayDiff < 0) arrTime += QString::number(arrDayDiff); - JourneyResultItem* journey = new JourneyResultItem(journeyList); + JourneyResultItem* journey = new JourneyResultItem(lastJourneyResultList); journey->setId(journeyID); journey->setDate(segments.first()->departureDateTime().date()); journey->setDepartureTime(depTime); @@ -487,7 +501,7 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) journey->setTrainType(transportModes.join(", ")); journey->setDuration(duration); journey->setTransfers(QString::number(transportModes.count()-1)); - journeyList->appendItem(journey); + lastJourneyResultList->appendItem(journey); if (journeyCounter == 0) { if (lastJourneySearch.mode == Departure) @@ -502,16 +516,16 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) ++journeyCounter; } - journeyList->setDepartureStation(lastJourneySearch.from.name); - journeyList->setArrivalStation(lastJourneySearch.to.name); + lastJourneyResultList->setDepartureStation(lastJourneySearch.from.name); + lastJourneyResultList->setArrivalStation(lastJourneySearch.to.name); QString modeString; if (lastJourneySearch.mode == Arrival) modeString = tr("Arrivals"); else modeString = tr("Departures"); - journeyList->setTimeInfo(modeString + " " + lastJourneySearch.dateTime.toString(tr("ddd MMM d, HH:mm"))); + lastJourneyResultList->setTimeInfo(modeString + " " + lastJourneySearch.dateTime.toString(tr("ddd MMM d, HH:mm"))); - emit journeyResult(journeyList); + emit journeyResult(lastJourneyResultList); } // Parse info about one journey option. Store detailed info about segments for later use. diff --git a/src/parser/parser_resrobot.h b/src/parser/parser_resrobot.h index 3ddef51a..9d17664b 100644 --- a/src/parser/parser_resrobot.h +++ b/src/parser/parser_resrobot.h @@ -60,6 +60,7 @@ class ParserResRobot : public ParserAbstract Q_OBJECT public: explicit ParserResRobot(QObject *parent = 0); + virtual ~ParserResRobot(); static QString getName() { return QString("%1 (resrobot.se)").arg(tr("Sweden")); } virtual QString name() { return getName(); } @@ -84,6 +85,7 @@ public slots: virtual void searchJourneyLater(); virtual void searchJourneyEarlier(); virtual void getJourneyDetails(const QString &id); + virtual void clearJourney(); protected: virtual void parseTimeTable(QNetworkReply *networkReply); @@ -94,6 +96,8 @@ public slots: virtual void parseSearchEarlierJourney(QNetworkReply *networkReply); virtual void parseJourneyDetails(QNetworkReply *networkReply); + JourneyResultList *lastJourneyResultList; + private: enum transportModePreset { ALL_TRANSPORT_MODES, From fe93c9734ab22307c618b6a3aea3fabf9f8bc276 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 1 Jun 2015 00:33:23 +0200 Subject: [PATCH 45/85] providing clearJourney at the top level --- src/parser/parser_abstract.cpp | 8 +++++++- src/parser/parser_abstract.h | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/parser/parser_abstract.cpp b/src/parser/parser_abstract.cpp index 86ade9e1..a9c99bd9 100644 --- a/src/parser/parser_abstract.cpp +++ b/src/parser/parser_abstract.cpp @@ -43,7 +43,7 @@ ParserAbstract::ParserAbstract(QObject *parent) : currentRequestState = FahrplanNS::noneRequest; - requestTimeout = new QTimer(); + requestTimeout = new QTimer(this); connect(requestTimeout, SIGNAL(timeout()), this, SLOT(networkReplyTimedOut())); @@ -52,10 +52,16 @@ ParserAbstract::ParserAbstract(QObject *parent) : ParserAbstract::~ParserAbstract() { + clearJourney(); delete requestTimeout; delete NetworkManager; } +void ParserAbstract::clearJourney() +{ + +} + void ParserAbstract::networkReplyFinished(QNetworkReply *networkReply) { FahrplanNS::curReqStates internalRequestState = currentRequestState; diff --git a/src/parser/parser_abstract.h b/src/parser/parser_abstract.h index 969799ad..af236afd 100644 --- a/src/parser/parser_abstract.h +++ b/src/parser/parser_abstract.h @@ -37,7 +37,7 @@ class ParserAbstract : public QObject enum Mode { Departure = 0, Arrival = 1 }; explicit ParserAbstract(QObject *parent = 0); - ~ParserAbstract(); + virtual ~ParserAbstract(); static QString getName() { return "Abstract"; } virtual QString name() { return getName(); } @@ -58,6 +58,7 @@ public slots: virtual bool supportsTimeTableDirection(); virtual QStringList getTrainRestrictions(); void cancelRequest(); + virtual void clearJourney(); signals: void stationsResult(const StationsList &result); From 57a638d0a30bcae89a35ec5d7130f15a6d115db3 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 25 May 2015 00:46:48 +0200 Subject: [PATCH 46/85] added missed parents --- src/parser/parser_resrobot.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/parser/parser_resrobot.cpp b/src/parser/parser_resrobot.cpp index d097fbb5..9af730ab 100644 --- a/src/parser/parser_resrobot.cpp +++ b/src/parser/parser_resrobot.cpp @@ -537,7 +537,11 @@ QList ParserResRobot::parseJourneySegments(const QVari foreach (QVariant segmentData, segments) { QVariantMap segment = segmentData.toMap(); +<<<<<<< HEAD JourneyDetailResultItem* resultItem = new JourneyDetailResultItem;//FIXME will leak in QML +======= + JourneyDetailResultItem* resultItem = new JourneyDetailResultItem(results); +>>>>>>> added missed parents // Departure QVariantMap departure = segment.value("departure").toMap(); From 42c88a839e330ab89941859d16d44809c298bae7 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 25 May 2015 01:02:20 +0200 Subject: [PATCH 47/85] not that easy there, leaving a FIXME for the next round --- src/parser/parser_resrobot.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/parser/parser_resrobot.cpp b/src/parser/parser_resrobot.cpp index 9af730ab..ba066176 100644 --- a/src/parser/parser_resrobot.cpp +++ b/src/parser/parser_resrobot.cpp @@ -537,11 +537,15 @@ QList ParserResRobot::parseJourneySegments(const QVari foreach (QVariant segmentData, segments) { QVariantMap segment = segmentData.toMap(); +<<<<<<< HEAD <<<<<<< HEAD JourneyDetailResultItem* resultItem = new JourneyDetailResultItem;//FIXME will leak in QML ======= JourneyDetailResultItem* resultItem = new JourneyDetailResultItem(results); >>>>>>> added missed parents +======= + JourneyDetailResultItem* resultItem = new JourneyDetailResultItem;//FIXME will leak in QML +>>>>>>> not that easy there, leaving a FIXME for the next round // Departure QVariantMap departure = segment.value("departure").toMap(); From a43589c4e1636002702e746f38234f14d8163bc5 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Thu, 28 May 2015 02:13:38 +0200 Subject: [PATCH 48/85] fixing leaks --- src/parser/parser_hafasxml.cpp | 4 ++++ src/parser/parser_hafasxml.h | 1 + 2 files changed, 5 insertions(+) diff --git a/src/parser/parser_hafasxml.cpp b/src/parser/parser_hafasxml.cpp index ec0ec1cf..35cc5123 100644 --- a/src/parser/parser_hafasxml.cpp +++ b/src/parser/parser_hafasxml.cpp @@ -539,7 +539,11 @@ void ParserHafasXml::searchJourney(const Station &departureStation, const Statio currentRequestState = FahrplanNS::searchJourneyRequest; hafasContext.seqNr = ""; +<<<<<<< HEAD clearJourney(); +======= + cleanupJourney(); +>>>>>>> fixing leaks QString trainrestr = getTrainRestrictionsCodes(trainrestrictions); diff --git a/src/parser/parser_hafasxml.h b/src/parser/parser_hafasxml.h index 513d206a..d6e2ca9f 100644 --- a/src/parser/parser_hafasxml.h +++ b/src/parser/parser_hafasxml.h @@ -92,6 +92,7 @@ public slots: void parseSearchLaterJourney(QNetworkReply *networkReply); void parseSearchEarlierJourney(QNetworkReply *networkReply); void parseJourneyDetails(QNetworkReply *networkReply); + void cleanupJourney(); virtual QString getTrainRestrictionsCodes(int trainrestrictions); JourneyResultList *lastJourneyResultList; From 92be2e1f5eaeae4dc3d84572c856eedd552d403d Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Sun, 31 May 2015 23:27:52 +0200 Subject: [PATCH 49/85] clearJourney() is a more proper name --- src/parser/parser_hafasxml.cpp | 4 ---- src/parser/parser_hafasxml.h | 1 - 2 files changed, 5 deletions(-) diff --git a/src/parser/parser_hafasxml.cpp b/src/parser/parser_hafasxml.cpp index 35cc5123..ec0ec1cf 100644 --- a/src/parser/parser_hafasxml.cpp +++ b/src/parser/parser_hafasxml.cpp @@ -539,11 +539,7 @@ void ParserHafasXml::searchJourney(const Station &departureStation, const Statio currentRequestState = FahrplanNS::searchJourneyRequest; hafasContext.seqNr = ""; -<<<<<<< HEAD clearJourney(); -======= - cleanupJourney(); ->>>>>>> fixing leaks QString trainrestr = getTrainRestrictionsCodes(trainrestrictions); diff --git a/src/parser/parser_hafasxml.h b/src/parser/parser_hafasxml.h index d6e2ca9f..513d206a 100644 --- a/src/parser/parser_hafasxml.h +++ b/src/parser/parser_hafasxml.h @@ -92,7 +92,6 @@ public slots: void parseSearchLaterJourney(QNetworkReply *networkReply); void parseSearchEarlierJourney(QNetworkReply *networkReply); void parseJourneyDetails(QNetworkReply *networkReply); - void cleanupJourney(); virtual QString getTrainRestrictionsCodes(int trainrestrictions); JourneyResultList *lastJourneyResultList; From ea6fcbb6aacb40590de18b4cd6d916d495dae5ce Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 1 Jun 2015 00:05:17 +0200 Subject: [PATCH 50/85] fixing ParserXmlVasttrafikSe memory leaks --- src/parser/parser_xmlvasttrafikse.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/parser/parser_xmlvasttrafikse.cpp b/src/parser/parser_xmlvasttrafikse.cpp index 02e682b1..abf75ab0 100644 --- a/src/parser/parser_xmlvasttrafikse.cpp +++ b/src/parser/parser_xmlvasttrafikse.cpp @@ -325,6 +325,15 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) clearJourney(); lastJourneyResultList = new JourneyResultList(this); +<<<<<<< HEAD +======= + + for (QHash::Iterator it = cachedJourneyDetails.begin(); it != cachedJourneyDetails.end();) { + JourneyDetailResultList *jdrl = it.value(); + it = cachedJourneyDetails.erase(it); + delete jdrl; + } +>>>>>>> fixing ParserXmlVasttrafikSe memory leaks /// Use fallback values for empty results (i.e. no connections found) lastJourneyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); From 4897391eba3737bc92d0f19333094621ea55bc8a Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Mon, 1 Jun 2015 00:28:42 +0200 Subject: [PATCH 51/85] one more small fix to vasttrafikse --- src/parser/parser_xmlvasttrafikse.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/parser/parser_xmlvasttrafikse.cpp b/src/parser/parser_xmlvasttrafikse.cpp index abf75ab0..02e682b1 100644 --- a/src/parser/parser_xmlvasttrafikse.cpp +++ b/src/parser/parser_xmlvasttrafikse.cpp @@ -325,15 +325,6 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) clearJourney(); lastJourneyResultList = new JourneyResultList(this); -<<<<<<< HEAD -======= - - for (QHash::Iterator it = cachedJourneyDetails.begin(); it != cachedJourneyDetails.end();) { - JourneyDetailResultList *jdrl = it.value(); - it = cachedJourneyDetails.erase(it); - delete jdrl; - } ->>>>>>> fixing ParserXmlVasttrafikSe memory leaks /// Use fallback values for empty results (i.e. no connections found) lastJourneyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); From 6930cf9191ca41c534efc4d20e5197661892e24f Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Sat, 13 Jun 2015 13:25:48 +0200 Subject: [PATCH 52/85] upstreaming --- src/parser/parser_resrobot.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/parser/parser_resrobot.cpp b/src/parser/parser_resrobot.cpp index ba066176..d097fbb5 100644 --- a/src/parser/parser_resrobot.cpp +++ b/src/parser/parser_resrobot.cpp @@ -537,15 +537,7 @@ QList ParserResRobot::parseJourneySegments(const QVari foreach (QVariant segmentData, segments) { QVariantMap segment = segmentData.toMap(); -<<<<<<< HEAD -<<<<<<< HEAD JourneyDetailResultItem* resultItem = new JourneyDetailResultItem;//FIXME will leak in QML -======= - JourneyDetailResultItem* resultItem = new JourneyDetailResultItem(results); ->>>>>>> added missed parents -======= - JourneyDetailResultItem* resultItem = new JourneyDetailResultItem;//FIXME will leak in QML ->>>>>>> not that easy there, leaving a FIXME for the next round // Departure QVariantMap departure = segment.value("departure").toMap(); From 1a1eb146b671de9cf02d743396ce18373293e3e5 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Sun, 14 Jun 2015 01:44:51 +0200 Subject: [PATCH 53/85] added clear journey api to be able to free memory as soon as possible --- src/fahrplan_parser_thread.cpp | 6 ++++++ src/fahrplan_parser_thread.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/src/fahrplan_parser_thread.cpp b/src/fahrplan_parser_thread.cpp index af3dea1d..8df1c093 100644 --- a/src/fahrplan_parser_thread.cpp +++ b/src/fahrplan_parser_thread.cpp @@ -76,6 +76,11 @@ void FahrplanParserThread::cancelRequest() emit requestCancelRequest(); } +void FahrplanParserThread::clearJourney() +{ + emit requestClearJourney(); +} + QString FahrplanParserThread::name() { return m_name; } @@ -182,6 +187,7 @@ void FahrplanParserThread::run() connect(this, SIGNAL(requestSearchJourney(Station,Station,Station,QDateTime,ParserAbstract::Mode,int)), m_parser, SLOT(searchJourney(Station,Station,Station,QDateTime,ParserAbstract::Mode,int)), Qt::QueuedConnection); connect(this, SIGNAL(requestSearchJourneyEarlier()), m_parser, SLOT(searchJourneyEarlier()), Qt::QueuedConnection); connect(this, SIGNAL(requestSearchJourneyLater()), m_parser, SLOT(searchJourneyLater()), Qt::QueuedConnection); + connect(this, SIGNAL(requestClearJourney()), m_parser, SLOT(clearJourney()), Qt::QueuedConnection); //Connect parser responses with threads corresponding results connect(m_parser, SIGNAL(errorOccured(QString)), this, SIGNAL(errorOccured(QString)), Qt::QueuedConnection); diff --git a/src/fahrplan_parser_thread.h b/src/fahrplan_parser_thread.h index 90a3d758..f0931215 100644 --- a/src/fahrplan_parser_thread.h +++ b/src/fahrplan_parser_thread.h @@ -56,6 +56,7 @@ class FahrplanParserThread : public QThread void requestSearchJourneyEarlier(); void requestGetJourneyDetails(const QString &id); void requestCancelRequest(); + void requestClearJourney(); //Real ones void stationsResult(const StationsList &result); @@ -75,6 +76,7 @@ public slots: void searchJourneyEarlier(); void getJourneyDetails(const QString &id); void cancelRequest(); + void clearJourney(); bool supportsGps(); bool supportsVia(); From 208ad3ed0293facab62b90e7f3e7faf7dda36484 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Sun, 14 Jun 2015 01:43:26 +0200 Subject: [PATCH 54/85] additional control on destruction --- src/fahrplan.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++++++-- src/fahrplan.h | 2 ++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/fahrplan.cpp b/src/fahrplan.cpp index f31baa03..7c3fd717 100644 --- a/src/fahrplan.cpp +++ b/src/fahrplan.cpp @@ -43,12 +43,12 @@ Fahrplan::Fahrplan(QObject *parent) , m_mode(DepartureMode) , m_dateTime(QDateTime::currentDateTime()) { - settings = new QSettings(FAHRPLAN_SETTINGS_NAMESPACE, "fahrplan2"); + settings = new QSettings(FAHRPLAN_SETTINGS_NAMESPACE, "fahrplan2", this); setMode(static_cast(settings->value("mode", DepartureMode).toInt())); if (!m_parser_manager) { int currentBackend = settings->value("currentBackend", 0).toInt(); - m_parser_manager = new FahrplanBackendManager(currentBackend); + m_parser_manager = new FahrplanBackendManager(currentBackend, this); } connect(m_parser_manager, SIGNAL(parserChanged(const QString &, int)), this, SLOT(onParserChanged(const QString &, int))); @@ -73,6 +73,41 @@ Fahrplan::Fahrplan(QObject *parent) } } +Fahrplan::~Fahrplan() +{ + qDebug() << this; + + if (m_trainrestrictions) { + delete m_trainrestrictions; + } + + if (m_timetable) { + delete m_timetable; + } + + if (m_stationSearchResults) { + disconnect(m_stationSearchResults, SIGNAL(stationSelected(Fahrplan::StationType,Station)), + this, SLOT(setStation(Fahrplan::StationType,Station))); + delete m_stationSearchResults; + } + + if (m_favorites) { + disconnect(m_favorites, SIGNAL(stationSelected(Fahrplan::StationType,Station)), + this, SLOT(setStation(Fahrplan::StationType,Station))); + delete m_favorites; + } + + if (m_parser_manager) { + unbindParserSignals(); + disconnect(m_parser_manager, SIGNAL(parserChanged(const QString &, int)), this, SLOT(onParserChanged(const QString &, int))); + delete m_parser_manager; + } + + if (settings) { + delete settings; + } +} + void Fahrplan::bindParserSignals() { if (m_parser_manager->getParser()) { @@ -84,6 +119,17 @@ void Fahrplan::bindParserSignals() } } +void Fahrplan::unbindParserSignals() +{ + if (m_parser_manager->getParser()) { + disconnect(m_parser_manager->getParser(), SIGNAL(stationsResult(StationsList)), this, SLOT(onStationSearchResults(StationsList))); + disconnect(m_parser_manager->getParser(), SIGNAL(journeyResult(JourneyResultList*)), this, SIGNAL(parserJourneyResult(JourneyResultList*))); + disconnect(m_parser_manager->getParser(), SIGNAL(errorOccured(QString)), this, SIGNAL(parserErrorOccured(QString))); + disconnect(m_parser_manager->getParser(), SIGNAL(journeyDetailsResult(JourneyDetailResultList*)), this, SIGNAL(parserJourneyDetailsResult(JourneyDetailResultList*))); + disconnect(m_parser_manager->getParser(), SIGNAL(timeTableResult(TimetableEntriesList)), this, SLOT(onTimetableResult(TimetableEntriesList))); + } +} + void Fahrplan::storeSettingsValue(const QString &key, const QString &value) { settings->setValue(key, value); diff --git a/src/fahrplan.h b/src/fahrplan.h index 1515a94c..a92f29e7 100644 --- a/src/fahrplan.h +++ b/src/fahrplan.h @@ -77,6 +77,7 @@ class Fahrplan : public QObject }; explicit Fahrplan(QObject *parent = 0); + virtual ~Fahrplan(); FahrplanParserThread *parser(); Favorites *favorites() const; QString parserName() const; @@ -141,6 +142,7 @@ class Fahrplan : public QObject void onStationSearchResults(const StationsList &result); void onTimetableResult(const TimetableEntriesList &timetableEntries); void bindParserSignals(); + void unbindParserSignals(); private: static FahrplanBackendManager *m_parser_manager; From 6ab413e3d783982788d4f13bde92f072acb54085 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Fri, 19 Jun 2015 02:22:49 +0200 Subject: [PATCH 55/85] minor ownership fixes and memory leak fixes (cherry picked from commit 177a939ee2a54cdddc84ab27a3bf9fe700a1cb25) --- src/parser/parser_efa.cpp | 34 +++++++++++++-------------- src/parser/parser_hafasxml.cpp | 2 +- src/parser/parser_xmlvasttrafikse.cpp | 4 ++-- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/parser/parser_efa.cpp b/src/parser/parser_efa.cpp index 3fe3a3a4..e8a1e728 100755 --- a/src/parser/parser_efa.cpp +++ b/src/parser/parser_efa.cpp @@ -519,7 +519,7 @@ void ParserEFA::parseSearchJourney(QNetworkReply *networkReply) qDebug() << "ParserEFA::parseSearchJourney(QNetworkReply *networkReply)"; clearJourney(); - lastJourneyResultList = new JourneyResultList(); + lastJourneyResultList = new JourneyResultList(this); for (QHash::Iterator it = cachedJourneyDetailsEfa.begin(); it != cachedJourneyDetailsEfa.end();) { JourneyDetailResultList *jdrl = it.value(); @@ -634,20 +634,19 @@ void ParserEFA::searchJourneyLater() { qDebug() << "ParserEFA::searchJourneyLater()"; - if (m_latestResultDeparture.isValid()) - { + if (m_latestResultDeparture.isValid()) { qDebug() << "m_latestResultDeparture.isValid()"; searchJourney(m_searchJourneyParameters.departureStation, m_searchJourneyParameters.viaStation, m_searchJourneyParameters.arrivalStation, m_latestResultDeparture, Departure, 0); - } - else { + } else { qDebug() << "!m_latestResultDeparture.isValid(), "; - JourneyResultList *journeyResultList = new JourneyResultList(); - journeyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); - journeyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); - journeyResultList->setArrivalStation(m_searchJourneyParameters.arrivalStation.name); + clearJourney(); + lastJourneyResultList = new JourneyResultList(this); + lastJourneyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); + lastJourneyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); + lastJourneyResultList->setArrivalStation(m_searchJourneyParameters.arrivalStation.name); //: DATE, TIME - journeyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(m_searchJourneyParameters.dateTime.date().toString(Qt::DefaultLocaleShortDate)).arg(m_searchJourneyParameters.dateTime.time().toString(Qt::DefaultLocaleShortDate))); - emit journeyResult(journeyResultList); + lastJourneyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(m_searchJourneyParameters.dateTime.date().toString(Qt::DefaultLocaleShortDate)).arg(m_searchJourneyParameters.dateTime.time().toString(Qt::DefaultLocaleShortDate))); + emit journeyResult(lastJourneyResultList); } } @@ -657,13 +656,14 @@ void ParserEFA::searchJourneyEarlier() if (m_earliestArrival.isValid()) searchJourney(m_searchJourneyParameters.departureStation, m_searchJourneyParameters.viaStation, m_searchJourneyParameters.arrivalStation, m_earliestArrival, Arrival, 0); else { - JourneyResultList *journeyResultList = new JourneyResultList(); - journeyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); - journeyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); - journeyResultList->setArrivalStation(m_searchJourneyParameters.arrivalStation.name); + clearJourney(); + lastJourneyResultList = new JourneyResultList(this); + lastJourneyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); + lastJourneyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); + lastJourneyResultList->setArrivalStation(m_searchJourneyParameters.arrivalStation.name); //: DATE, TIME - journeyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(m_searchJourneyParameters.dateTime.date().toString(Qt::DefaultLocaleShortDate)).arg(m_searchJourneyParameters.dateTime.time().toString(Qt::DefaultLocaleShortDate))); - emit journeyResult(journeyResultList); + lastJourneyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(m_searchJourneyParameters.dateTime.date().toString(Qt::DefaultLocaleShortDate)).arg(m_searchJourneyParameters.dateTime.time().toString(Qt::DefaultLocaleShortDate))); + emit journeyResult(lastJourneyResultList); } } diff --git a/src/parser/parser_hafasxml.cpp b/src/parser/parser_hafasxml.cpp index ec0ec1cf..d0ee1b49 100644 --- a/src/parser/parser_hafasxml.cpp +++ b/src/parser/parser_hafasxml.cpp @@ -668,7 +668,7 @@ QString ParserHafasXml::parseExternalIds(const QVariant &id) const void ParserHafasXml::parseSearchJourney(QNetworkReply *networkReply) { - lastJourneyResultList = new JourneyResultList(); + lastJourneyResultList = new JourneyResultList(this); QDomDocument doc; if (!parseXml(doc, networkReply->readAll())) diff --git a/src/parser/parser_xmlvasttrafikse.cpp b/src/parser/parser_xmlvasttrafikse.cpp index 02e682b1..1434bec3 100644 --- a/src/parser/parser_xmlvasttrafikse.cpp +++ b/src/parser/parser_xmlvasttrafikse.cpp @@ -483,7 +483,7 @@ void ParserXmlVasttrafikSe::searchJourneyLater() searchJourney(m_searchJourneyParameters.departureStation, m_searchJourneyParameters.arrivalStation, m_searchJourneyParameters.viaStation, m_latestResultDeparture, Departure, 0); else { clearJourney(); - lastJourneyResultList = new JourneyResultList(); + lastJourneyResultList = new JourneyResultList(this); lastJourneyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); lastJourneyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); lastJourneyResultList->setArrivalStation(m_searchJourneyParameters.arrivalStation.name); @@ -499,7 +499,7 @@ void ParserXmlVasttrafikSe::searchJourneyEarlier() searchJourney(m_searchJourneyParameters.departureStation, m_searchJourneyParameters.arrivalStation, m_searchJourneyParameters.viaStation, m_earliestArrival, Arrival, 0); else { clearJourney(); - lastJourneyResultList = new JourneyResultList(); + lastJourneyResultList = new JourneyResultList(this); lastJourneyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); lastJourneyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); lastJourneyResultList->setArrivalStation(m_searchJourneyParameters.arrivalStation.name); From 4db74e884480d94d24f27f08d7a6645cbdb8915a Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Fri, 19 Jun 2015 02:49:22 +0200 Subject: [PATCH 56/85] cleaning up lastJourneyResultList initialization in ctors --- src/parser/parser_abstract.cpp | 2 +- src/parser/parser_efa.cpp | 3 ++- src/parser/parser_hafasxml.cpp | 4 +--- src/parser/parser_ninetwo.cpp | 2 +- src/parser/parser_resrobot.cpp | 1 + src/parser/parser_xmlvasttrafikse.cpp | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/parser/parser_abstract.cpp b/src/parser/parser_abstract.cpp index a9c99bd9..13d47901 100644 --- a/src/parser/parser_abstract.cpp +++ b/src/parser/parser_abstract.cpp @@ -36,7 +36,7 @@ #endif ParserAbstract::ParserAbstract(QObject *parent) : - QObject(parent) + QObject(parent), lastRequest(NULL) { NetworkManager = new QNetworkAccessManager(this); connect(NetworkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkReplyFinished(QNetworkReply*))); diff --git a/src/parser/parser_efa.cpp b/src/parser/parser_efa.cpp index e8a1e728..2fc585b1 100755 --- a/src/parser/parser_efa.cpp +++ b/src/parser/parser_efa.cpp @@ -102,7 +102,8 @@ QHash cachedJourneyDetailsEfa; ParserEFA::ParserEFA(QObject *parent) : - ParserAbstract(parent){ + ParserAbstract(parent), lastJourneyResultList(NULL) +{ m_searchJourneyParameters.isValid = false; m_timeTableForStationParameters.isValid = false; diff --git a/src/parser/parser_hafasxml.cpp b/src/parser/parser_hafasxml.cpp index d0ee1b49..8f2cb18a 100644 --- a/src/parser/parser_hafasxml.cpp +++ b/src/parser/parser_hafasxml.cpp @@ -32,7 +32,7 @@ // http://stefanwehrmeyer.com/projects/vbbxsd/ ParserHafasXml::ParserHafasXml(QObject *parent) : - ParserAbstract(parent) + ParserAbstract(parent), lastJourneyResultList(NULL) { //baseUrl = "http://fahrplan.oebb.at/bin/query.exe"; //OEB (fully operational/no RT) //no xmlhandle, detaildate already present! //baseUrl = "http://hafas.bene-system.com/bin/query.exe"; //hafas dev?? system? / no gps @@ -48,8 +48,6 @@ ParserHafasXml::ParserHafasXml(QObject *parent) : hafasHeader.ver = "1.1"; STTableMode = 0; - - lastJourneyResultList = NULL; } ParserHafasXml::~ParserHafasXml() diff --git a/src/parser/parser_ninetwo.cpp b/src/parser/parser_ninetwo.cpp index 95d88b2f..2587d778 100644 --- a/src/parser/parser_ninetwo.cpp +++ b/src/parser/parser_ninetwo.cpp @@ -49,7 +49,7 @@ inline int distance(qreal lat1, qreal lon1, qreal lat2, qreal lon2) return qRound(6371.0 * c * 1000); } -ParserNinetwo::ParserNinetwo(QObject *parent):ParserAbstract(parent) +ParserNinetwo::ParserNinetwo(QObject *parent):ParserAbstract(parent), lastJourneyResultList(NULL) { lastCoordinates.isValid = false; } diff --git a/src/parser/parser_resrobot.cpp b/src/parser/parser_resrobot.cpp index d097fbb5..a47d1f7a 100644 --- a/src/parser/parser_resrobot.cpp +++ b/src/parser/parser_resrobot.cpp @@ -27,6 +27,7 @@ ParserResRobot::ParserResRobot(QObject *parent) : ParserAbstract(parent), + lastJourneyResultList(NULL), timetableAPIKey(QLatin1String("en9A5GyxZLB98ZYjX8rkSNyHkurGb81G")), journeyAPIKey(QLatin1String("gcyYB9moXYXOTY2dAb06k7GAAOiZVXZr")), timetableBaseURL(QLatin1String("https://api.trafiklab.se/samtrafiken/resrobotstops/")), diff --git a/src/parser/parser_xmlvasttrafikse.cpp b/src/parser/parser_xmlvasttrafikse.cpp index 1434bec3..f2c699cd 100644 --- a/src/parser/parser_xmlvasttrafikse.cpp +++ b/src/parser/parser_xmlvasttrafikse.cpp @@ -40,7 +40,7 @@ QHash cachedJourneyDetails; #define getAttribute(node, key) (node.attributes().namedItem(key).toAttr().value()) ParserXmlVasttrafikSe::ParserXmlVasttrafikSe(QObject *parent) - : ParserAbstract(parent), apiKey(QLatin1String("47c5abaf-49d6-4c23-a1bd-b2e2766c4de7")), baseRestUrl(QLatin1String("http://api.vasttrafik.se/bin/rest.exe/v1/")) + : ParserAbstract(parent), lastJourneyResultList(NULL), apiKey(QLatin1String("47c5abaf-49d6-4c23-a1bd-b2e2766c4de7")), baseRestUrl(QLatin1String("http://api.vasttrafik.se/bin/rest.exe/v1/")) { m_searchJourneyParameters.isValid = false; m_timeTableForStationParameters.isValid = false; From 16fc03937471d01402f5d21334fc9adc5ea92d23 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Fri, 19 Jun 2015 19:53:43 +0200 Subject: [PATCH 57/85] finalizing cleanups and fixes --- src/parser/parser_efa.cpp | 25 +++-- src/parser/parser_efa.h | 1 + src/parser/parser_hafasxml.cpp | 2 +- src/parser/parser_ninetwo.cpp | 18 +++- src/parser/parser_resrobot.cpp | 190 +++++++++++++++++++++------------ src/parser/parser_resrobot.h | 2 +- 6 files changed, 157 insertions(+), 81 deletions(-) diff --git a/src/parser/parser_efa.cpp b/src/parser/parser_efa.cpp index 2fc585b1..f9f8e0f6 100755 --- a/src/parser/parser_efa.cpp +++ b/src/parser/parser_efa.cpp @@ -99,7 +99,7 @@ #include #endif -QHash cachedJourneyDetailsEfa; +//QHash cachedJourneyDetailsEfa; ParserEFA::ParserEFA(QObject *parent) : ParserAbstract(parent), lastJourneyResultList(NULL) @@ -116,6 +116,12 @@ ParserEFA::~ParserEFA() void ParserEFA::clearJourney() { + for (QHash::Iterator it = cachedJourneyDetailsEfa.begin(); it != cachedJourneyDetailsEfa.end();) { + JourneyDetailResultList *jdrl = it.value(); + it = cachedJourneyDetailsEfa.erase(it); + delete jdrl; + } + if (lastJourneyResultList) { delete lastJourneyResultList; lastJourneyResultList = NULL; @@ -522,12 +528,6 @@ void ParserEFA::parseSearchJourney(QNetworkReply *networkReply) lastJourneyResultList = new JourneyResultList(this); - for (QHash::Iterator it = cachedJourneyDetailsEfa.begin(); it != cachedJourneyDetailsEfa.end();) { - JourneyDetailResultList *jdrl = it.value(); - it = cachedJourneyDetailsEfa.erase(it); - delete jdrl; - } - /// Use fallback values for empty results (i.e. no connections found) lastJourneyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); lastJourneyResultList->setViaStation(m_searchJourneyParameters.viaStation.name); @@ -544,7 +544,7 @@ void ParserEFA::parseSearchJourney(QNetworkReply *networkReply) QDomElement route = doc.firstChildElement("itdRequest").firstChildElement("itdTripRequest").firstChildElement("itdItinerary").firstChildElement("itdRouteList").firstChildElement("itdRoute"); for (; !route.isNull(); route = route.nextSiblingElement("itdRoute")) { QStringList motNameList; - JourneyDetailResultList *detailsList = new JourneyDetailResultList(); + JourneyDetailResultList *detailsList = new JourneyDetailResultList(this); QDomElement partialRoute = route.firstChildElement("itdPartialRouteList").firstChildElement("itdPartialRoute"); for (; !partialRoute.isNull(); partialRoute = partialRoute.nextSiblingElement("itdPartialRoute")) { QDomElement motElement = partialRoute.firstChildElement("itdMeansOfTransport"); @@ -594,7 +594,7 @@ void ParserEFA::parseSearchJourney(QNetworkReply *networkReply) detailsList->setDuration(duration); detailsList->setArrivalDateTime(arrivalDateTime); detailsList->setDepartureDateTime(departureDateTime); - cachedJourneyDetailsEfa[id] = detailsList; + cachedJourneyDetailsEfa.insert(id, detailsList); JourneyResultItem *item = new JourneyResultItem(lastJourneyResultList); item->setDate(departureDateTime.date()); @@ -607,10 +607,13 @@ void ParserEFA::parseSearchJourney(QNetworkReply *networkReply) item->setArrivalTime(arrivalDateTime.toString("hh:mm")); lastJourneyResultList->appendItem(item); - if (!m_earliestArrival.isValid() || arrivalDateTime < m_earliestArrival) + if (!m_earliestArrival.isValid() || arrivalDateTime < m_earliestArrival) { m_earliestArrival = arrivalDateTime.addSecs(-60); - if (!m_latestResultDeparture.isValid() || departureDateTime > m_latestResultDeparture) + } + + if (!m_latestResultDeparture.isValid() || departureDateTime > m_latestResultDeparture) { m_latestResultDeparture = departureDateTime.addSecs(60); + } } checkForError(&doc); diff --git a/src/parser/parser_efa.h b/src/parser/parser_efa.h index c31e3cfc..6d95cc93 100755 --- a/src/parser/parser_efa.h +++ b/src/parser/parser_efa.h @@ -61,6 +61,7 @@ public slots: private: JourneyResultList *lastJourneyResultList; + QHash cachedJourneyDetailsEfa; struct { bool isValid; diff --git a/src/parser/parser_hafasxml.cpp b/src/parser/parser_hafasxml.cpp index 8f2cb18a..4285b975 100644 --- a/src/parser/parser_hafasxml.cpp +++ b/src/parser/parser_hafasxml.cpp @@ -860,7 +860,7 @@ void ParserHafasXml::getJourneyDetails(const QString &id) JourneyDetailResultList* ParserHafasXml::internalParseJourneyDetails(const QDomElement &connection) { - JourneyDetailResultList *results = new JourneyDetailResultList(); + JourneyDetailResultList *results = new JourneyDetailResultList(this); const QDomNodeList sections = connection.elementsByTagName("ConSection"); for (int i = 0; i < sections.count(); ++i) { diff --git a/src/parser/parser_ninetwo.cpp b/src/parser/parser_ninetwo.cpp index 2587d778..b70378c9 100644 --- a/src/parser/parser_ninetwo.cpp +++ b/src/parser/parser_ninetwo.cpp @@ -353,6 +353,18 @@ void ParserNinetwo::parseSearchJourney(QNetworkReply *networkReply) return; } + if (doc.contains("error")) { + QString error = doc.value("error").toString(); + QString message; + if (error == "NoJourneys") { + message = tr("No connections have been found that correspond to your request."); + } else { + message = tr("Unknown error ocurred with the backend (error %1).").arg(error); + } + emit errorOccured(message); + return; + } + QVariantList journeys = doc.value("journeys").toList(); clearJourney(); @@ -370,9 +382,11 @@ void ParserNinetwo::parseSearchJourney(QNetworkReply *networkReply) arrival = QDateTime::fromString(journey.value("arrival").toString(), "yyyy-MM-ddTHH:mm"); departure = QDateTime::fromString(journey.value("departure").toString(), "yyyy-MM-ddTHH:mm"); - if (i == journeys.constBegin()) - lastsearch.firstOption=departure; + if (i == journeys.constBegin()) { + lastsearch.firstOption = departure; + } + item->setDate(departure.date()); item->setArrivalTime(arrival.toString("HH:mm")); item->setDepartureTime(departure.toString("HH:mm")); diff --git a/src/parser/parser_resrobot.cpp b/src/parser/parser_resrobot.cpp index a47d1f7a..025c3097 100644 --- a/src/parser/parser_resrobot.cpp +++ b/src/parser/parser_resrobot.cpp @@ -95,6 +95,12 @@ ParserResRobot::~ParserResRobot() void ParserResRobot::clearJourney() { + for (QHash::Iterator it = cachedResults.begin(); it != cachedResults.end();) { + JourneyDetailResultList *jdrl = it.value(); + it = cachedResults.erase(it); + delete jdrl; + } + if (lastJourneyResultList) { delete lastJourneyResultList; lastJourneyResultList = NULL; @@ -133,10 +139,14 @@ QStringList ParserResRobot::getTrainRestrictions() void ParserResRobot::findStationsByName(const QString &stationName) { lastStationSearch = stationName; - if (stationName.length() < 2) + if (stationName.length() < 2) { return; - if (currentRequestState != FahrplanNS::noneRequest) + } + + if (currentRequestState != FahrplanNS::noneRequest) { return; + } + currentRequestState = FahrplanNS::stationsByNameRequest; QUrl url(journeyBaseURL + QLatin1String("FindLocation.json")); @@ -159,8 +169,10 @@ void ParserResRobot::findStationsByName(const QString &stationName) void ParserResRobot::findStationsByCoordinates(qreal longitude, qreal latitude) { - if (currentRequestState != FahrplanNS::noneRequest) + if (currentRequestState != FahrplanNS::noneRequest) { return; + } + currentRequestState = FahrplanNS::stationsByCoordinatesRequest; QUrl url(journeyBaseURL + QLatin1String("StationsInZone.json")); @@ -194,15 +206,19 @@ void ParserResRobot::getTimeTableForStation(const Station ¤tStation, Q_UNUSED(mode) Q_UNUSED(trainrestrictions) - if (currentRequestState != FahrplanNS::noneRequest) + if (currentRequestState != FahrplanNS::noneRequest) { return; + } + currentRequestState = FahrplanNS::getTimeTableForStationRequest; QUrl url; - if (realtime) + if (realtime) { url = realtimeTimetableBaseURL + QLatin1String("GetDepartures.json"); - else + } else { url = timetableBaseURL + QLatin1String("GetDepartures.json"); + } + #if defined(BUILD_FOR_QT5) QUrlQuery query; #else @@ -225,8 +241,10 @@ void ParserResRobot::searchJourney(const Station &departureStation, const Statio const Station &arrivalStation, const QDateTime &dateTime, ParserAbstract::Mode mode, int trainRestrictions) { - if (currentRequestState != FahrplanNS::noneRequest) + if (currentRequestState != FahrplanNS::noneRequest) { return; + } + currentRequestState = FahrplanNS::searchJourneyRequest; numberOfUnsuccessfulEarlierSearches = 0; numberOfUnsuccessfulLaterSearches = 0; @@ -238,10 +256,12 @@ void ParserResRobot::searchJourneyLater() // If the last "later" search didn't give any new results, try searching one // hour later than last time, otherwise search on the time of the last result option. QDateTime time; - if (lastJourneySearch.mode == Departure) + if (lastJourneySearch.mode == Departure) { time = lastJourneySearch.lastOption.addSecs(numberOfUnsuccessfulLaterSearches * 3600); - else + } else { time = lastJourneySearch.lastOption.addSecs(numberOfUnsuccessfulLaterSearches * 3600 + 3600); + } + currentRequestState = FahrplanNS::searchJourneyLaterRequest; internalSearchJourney(lastJourneySearch.from, lastJourneySearch.via, lastJourneySearch.to, time, lastJourneySearch.mode, lastJourneySearch.restrictions); @@ -253,10 +273,12 @@ void ParserResRobot::searchJourneyEarlier() // hour earlier than last time, otherwise search on the time of the first result // option minus one hour. QDateTime time; - if (lastJourneySearch.mode == Departure) + if (lastJourneySearch.mode == Departure) { time = lastJourneySearch.firstOption.addSecs(numberOfUnsuccessfulEarlierSearches * -3600 - 3600); - else + } else { time = lastJourneySearch.firstOption.addSecs(numberOfUnsuccessfulEarlierSearches * -3600); + } + currentRequestState = FahrplanNS::searchJourneyEarlierRequest; internalSearchJourney(lastJourneySearch.from, lastJourneySearch.via, lastJourneySearch.to, time, lastJourneySearch.mode, lastJourneySearch.restrictions); @@ -288,20 +310,25 @@ void ParserResRobot::internalSearchJourney(const Station &departureStation, cons query.addQueryItem("date", dateTime.toString("yyyy-MM-dd")); query.addQueryItem("time", dateTime.toString("hh:mm")); query.addQueryItem("coordSys", "WGS84"); - if (mode == Arrival) + + if (mode == Arrival) { query.addQueryItem("arrival", "true"); + } + QString transportModeCode; switch (trainRestrictions) { - default: - case ALL_TRANSPORT_MODES: - transportModeCode = "F"; - break; - case TRAIN_PUB_TRANS_NOT_EXP_BUS: - transportModeCode = "T"; - break; - case EXP_BUS_PUB_TRANS_NOT_TRAIN: - transportModeCode = "B"; - break; + case TRAIN_PUB_TRANS_NOT_EXP_BUS: + transportModeCode = "T"; + break; + + case EXP_BUS_PUB_TRANS_NOT_TRAIN: + transportModeCode = "B"; + break; + + case ALL_TRANSPORT_MODES: + default: + transportModeCode = "F"; + break; } query.addQueryItem("searchType", transportModeCode); @@ -326,8 +353,9 @@ void ParserResRobot::parseTimeTable(QNetworkReply *networkReply) QVariantMap departuresResult= doc.value("getdeparturesresult").toMap(); QVariantList timetableData; - if (departuresResult.contains("departuresegment")) + if (departuresResult.contains("departuresegment")) { timetableData = ensureList(departuresResult.value("departuresegment")); + } TimetableEntriesList timetable; foreach (QVariant timetableEntryData, timetableData) { @@ -348,8 +376,9 @@ void ParserResRobot::parseTimeTable(QNetworkReply *networkReply) QVariantMap realtimeInfo = entry.value("realtime").toMap(); bool hasDeviationInfo; int deviation = realtimeInfo.value("departuretimedeviation").toInt(&hasDeviationInfo); - if (hasDeviationInfo && deviation != 0) + if (hasDeviationInfo && deviation != 0) { resultItem.miscInfo = tr("New time: ") + resultItem.time.addSecs(deviation * 60).toString("HH:mm"); + } // Means of transportation QVariantMap mot = entry.value("segmentid").toMap().value("mot").toMap(); @@ -439,10 +468,9 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) QVariantMap timetableResult = doc.value("timetableresult").toMap(); QVariantList journeyListData; - if (timetableResult.contains("ttitem")) + if (timetableResult.contains("ttitem")) { journeyListData = ensureList(timetableResult.value("ttitem")); - - cachedResults.clear(); + } clearJourney(); lastJourneyResultList = new JourneyResultList(this); @@ -459,19 +487,16 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) minutes = minutes % 60; QString duration = QString("%1:%2").arg(hours).arg(minutes, 2, 10, QChar('0')); - // Compile list of transport modes used - QStringList transportModes; + JourneyDetailResultList* journeyDetails = new JourneyDetailResultList(this); + + QStringList transportModes; // Compile list of transport modes used foreach (JourneyDetailResultItem* segment, segments) { - if (segment->internalData1() != "WALK") + if (segment->internalData1() != "WALK") { transportModes.append(segment->train()); + } + journeyDetails->appendItem(segment); } - // When the distance is short, an option with only "walk" can be present - if (transportModes.count() == 0 && segments.count() == 1) - transportModes.append(segments.first()->train()); - JourneyDetailResultList* journeyDetails = new JourneyDetailResultList(this); - foreach (JourneyDetailResultItem* segment, segments) - journeyDetails->appendItem(segment); journeyDetails->setId(journeyID); journeyDetails->setDepartureStation(segments.first()->departureStation()); journeyDetails->setDepartureDateTime(segments.first()->departureDateTime()); @@ -480,13 +505,20 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) journeyDetails->setDuration(duration); cachedResults.insert(journeyID, journeyDetails); + // When the distance is short, an option with only "walk" can be present + if (transportModes.isEmpty() && segments.count() == 1) { + transportModes.append(segments.first()->train()); + } + // Indicate in the departure/arrival times if they are another day (e.g. "14:37+1") int depDayDiff = lastJourneySearch.dateTime.date().daysTo(journeyDetails->departureDateTime().date()); QString depTime = journeyDetails->departureDateTime().toString("HH:mm"); - if (depDayDiff > 0) + if (depDayDiff > 0) { depTime += "+" + QString::number(depDayDiff); - else if (depDayDiff < 0) + } else if (depDayDiff < 0) { depTime += QString::number(depDayDiff); + } + int arrDayDiff = lastJourneySearch.dateTime.date().daysTo(journeyDetails->arrivalDateTime().date()); QString arrTime = journeyDetails->arrivalDateTime().toString("HH:mm"); if (arrDayDiff > 0) @@ -505,25 +537,31 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) lastJourneyResultList->appendItem(journey); if (journeyCounter == 0) { - if (lastJourneySearch.mode == Departure) + if (lastJourneySearch.mode == Departure) { lastJourneySearch.firstOption = journeyDetails->departureDateTime(); - else + } else { lastJourneySearch.firstOption = journeyDetails->arrivalDateTime(); + } } - if (lastJourneySearch.mode == Departure) + + if (lastJourneySearch.mode == Departure) { lastJourneySearch.lastOption = journeyDetails->departureDateTime(); - else + } else { lastJourneySearch.lastOption = journeyDetails->arrivalDateTime(); + } ++journeyCounter; } lastJourneyResultList->setDepartureStation(lastJourneySearch.from.name); lastJourneyResultList->setArrivalStation(lastJourneySearch.to.name); + QString modeString; - if (lastJourneySearch.mode == Arrival) + if (lastJourneySearch.mode == Arrival) { modeString = tr("Arrivals"); - else + } else { modeString = tr("Departures"); + } + lastJourneyResultList->setTimeInfo(modeString + " " + lastJourneySearch.dateTime.toString(tr("ddd MMM d, HH:mm"))); emit journeyResult(lastJourneyResultList); @@ -535,10 +573,9 @@ QList ParserResRobot::parseJourneySegments(const QVari QList results; QVariantList segments = ensureList(journeyData.value("segment")); - foreach (QVariant segmentData, segments) - { + foreach (QVariant segmentData, segments) { QVariantMap segment = segmentData.toMap(); - JourneyDetailResultItem* resultItem = new JourneyDetailResultItem;//FIXME will leak in QML + JourneyDetailResultItem* resultItem = new JourneyDetailResultItem(this); // Departure QVariantMap departure = segment.value("departure").toMap(); @@ -565,35 +602,47 @@ QList ParserResRobot::parseJourneySegments(const QVari QString type = mot.value("@type").toString(); QString motName = translateTransportMode(mot.value("#text").toString()); QString distance; + if (type == "G" || type == "GL") { // Walk or long walk distance = segment.value("segmentid").toMap().value("distance").toString(); resultItem->setInternalData1("WALK"); } + QVariantMap carrier = segment.value("segmentid").toMap().value("carrier").toMap(); QString carrierInfo; if (carrier.size() > 0) { QString carrierNumber = carrier.value("number").toString(); - if (!carrierNumber.isEmpty()) + if (!carrierNumber.isEmpty()) { motName += " " + carrierNumber; + } QString carrierName = carrier.value("name").toString(); QString carrierURL = carrier.value("url").toString(); if (!carrierName.isEmpty()) { - if (carrierURL.isEmpty()) + if (carrierURL.isEmpty()) { carrierInfo = carrierName; - else + } else { carrierInfo = "" + carrierName + ""; + } } } resultItem->setTrain(motName); - if (!distance.isEmpty()) + if (distance.isEmpty()) { + QStringList infoList; + + if (!carrierInfo.isEmpty()) { + infoList << carrierInfo; + } + + if (!info.isEmpty()) { + infoList << info.join(", "); + } + + resultItem->setInfo(infoList.join("
")); + } else { resultItem->setInfo(distance + " m"); - else if (!carrierInfo.isEmpty() && !info.isEmpty()) - resultItem->setInfo(carrierInfo + "
" + info.join(", ")); - else if (!carrierInfo.isEmpty()) - resultItem->setInfo(carrierInfo); - else if (!info.isEmpty()) - resultItem->setInfo(info.join(", ")); + } + resultItem->setDirection(segment.value("direction").toString()); results.append(resultItem); @@ -603,8 +652,9 @@ QList ParserResRobot::parseJourneySegments(const QVari void ParserResRobot::getJourneyDetails(const QString &id) { - if (cachedResults.contains(id)) + if (cachedResults.contains(id)) { emit journeyDetailsResult(cachedResults.value(id)); + } } void ParserResRobot::parseSearchLaterJourney(QNetworkReply *networkReply) @@ -612,12 +662,16 @@ void ParserResRobot::parseSearchLaterJourney(QNetworkReply *networkReply) QDateTime oldFirstOption = lastJourneySearch.firstOption; QDateTime oldLastOption = lastJourneySearch.lastOption; parseSearchJourney(networkReply); - if (oldFirstOption != lastJourneySearch.firstOption) + + if (oldFirstOption != lastJourneySearch.firstOption) { numberOfUnsuccessfulEarlierSearches = 0; - if (oldLastOption != lastJourneySearch.lastOption) - numberOfUnsuccessfulLaterSearches = 0; - else + } + + if (oldLastOption == lastJourneySearch.lastOption) { ++numberOfUnsuccessfulLaterSearches; + } else { + numberOfUnsuccessfulLaterSearches = 0; + } } void ParserResRobot::parseSearchEarlierJourney(QNetworkReply *networkReply) @@ -625,12 +679,16 @@ void ParserResRobot::parseSearchEarlierJourney(QNetworkReply *networkReply) QDateTime oldFirstOption = lastJourneySearch.firstOption; QDateTime oldLastOption = lastJourneySearch.lastOption; parseSearchJourney(networkReply); - if (oldFirstOption != lastJourneySearch.firstOption) - numberOfUnsuccessfulEarlierSearches = 0; - else + + if (oldFirstOption == lastJourneySearch.firstOption) { ++numberOfUnsuccessfulEarlierSearches; - if (oldLastOption != lastJourneySearch.lastOption) + } else { + numberOfUnsuccessfulEarlierSearches = 0; + } + + if (oldLastOption != lastJourneySearch.lastOption) { numberOfUnsuccessfulLaterSearches = 0; + } } void ParserResRobot::parseJourneyDetails(QNetworkReply *networkReply) diff --git a/src/parser/parser_resrobot.h b/src/parser/parser_resrobot.h index 9d17664b..ecbfb422 100644 --- a/src/parser/parser_resrobot.h +++ b/src/parser/parser_resrobot.h @@ -127,7 +127,7 @@ public slots: const int nearbyRadius; // Define what is "nearby" in meters const int timetableSpan; // Minutes (valid values: 30 or 120) bool realtime; - QMap cachedResults; + QHash cachedResults; // Keep track of the number of "earlier"/"later" searches we did without getting any new results int numberOfUnsuccessfulEarlierSearches; int numberOfUnsuccessfulLaterSearches; From 047994227c8b99976a69ade7618a1a3f0b46d034 Mon Sep 17 00:00:00 2001 From: Kirill Plyashkevich Date: Tue, 23 Jun 2015 22:51:41 +0200 Subject: [PATCH 58/85] ensure calling clearJourney() in all the paths (search, search earlier, search later) --- src/parser/parser_efa.cpp | 3 ++- src/parser/parser_hafasbinary.cpp | 4 ++++ src/parser/parser_hafasxml.cpp | 4 ++++ src/parser/parser_ninetwo.cpp | 2 ++ src/parser/parser_resrobot.cpp | 6 +++++- src/parser/parser_xmlvasttrafikse.cpp | 3 ++- 6 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/parser/parser_efa.cpp b/src/parser/parser_efa.cpp index f9f8e0f6..9ece516b 100755 --- a/src/parser/parser_efa.cpp +++ b/src/parser/parser_efa.cpp @@ -422,6 +422,8 @@ void ParserEFA::searchJourney(const Station &departureStation, const Station &vi return; currentRequestState = FahrplanNS::searchJourneyRequest; + clearJourney(); + m_searchJourneyParameters.isValid = false; m_searchJourneyParameters.departureStation = departureStation; m_searchJourneyParameters.arrivalStation = arrivalStation; @@ -524,7 +526,6 @@ void ParserEFA::searchJourney(const Station &departureStation, const Station &vi void ParserEFA::parseSearchJourney(QNetworkReply *networkReply) { qDebug() << "ParserEFA::parseSearchJourney(QNetworkReply *networkReply)"; - clearJourney(); lastJourneyResultList = new JourneyResultList(this); diff --git a/src/parser/parser_hafasbinary.cpp b/src/parser/parser_hafasbinary.cpp index bce5fcde..42da5a31 100644 --- a/src/parser/parser_hafasbinary.cpp +++ b/src/parser/parser_hafasbinary.cpp @@ -634,6 +634,8 @@ void ParserHafasBinary::searchJourneyLater() currentRequestState = FahrplanNS::searchJourneyLaterRequest; + clearJourney(); + QUrl uri = baseBinaryUrl; #if defined(BUILD_FOR_QT5) QUrlQuery query; @@ -669,6 +671,8 @@ void ParserHafasBinary::searchJourneyEarlier() currentRequestState = FahrplanNS::searchJourneyEarlierRequest; + clearJourney(); + QUrl uri = baseBinaryUrl; #if defined(BUILD_FOR_QT5) QUrlQuery query; diff --git a/src/parser/parser_hafasxml.cpp b/src/parser/parser_hafasxml.cpp index 4285b975..ad4e9c46 100644 --- a/src/parser/parser_hafasxml.cpp +++ b/src/parser/parser_hafasxml.cpp @@ -767,6 +767,8 @@ void ParserHafasXml::searchJourneyLater() currentRequestState = FahrplanNS::searchJourneyLaterRequest; + clearJourney(); + QByteArray postData = ""; postData.append(""); postData.append(""); @@ -792,6 +794,8 @@ void ParserHafasXml::searchJourneyEarlier() currentRequestState = FahrplanNS::searchJourneyEarlierRequest; + clearJourney(); + QByteArray postData = ""; postData.append(""); postData.append(""); diff --git a/src/parser/parser_ninetwo.cpp b/src/parser/parser_ninetwo.cpp index b70378c9..aca8830d 100644 --- a/src/parser/parser_ninetwo.cpp +++ b/src/parser/parser_ninetwo.cpp @@ -185,6 +185,8 @@ void ParserNinetwo::searchJourney(const Station &departureStation, currentRequestState=FahrplanNS::searchJourneyRequest; + clearJourney(); + } void ParserNinetwo::searchJourneyLater() diff --git a/src/parser/parser_resrobot.cpp b/src/parser/parser_resrobot.cpp index 025c3097..e962175d 100644 --- a/src/parser/parser_resrobot.cpp +++ b/src/parser/parser_resrobot.cpp @@ -246,6 +246,9 @@ void ParserResRobot::searchJourney(const Station &departureStation, const Statio } currentRequestState = FahrplanNS::searchJourneyRequest; + + clearJourney(); + numberOfUnsuccessfulEarlierSearches = 0; numberOfUnsuccessfulLaterSearches = 0; internalSearchJourney(departureStation, viaStation, arrivalStation, dateTime, mode, trainRestrictions); @@ -263,6 +266,7 @@ void ParserResRobot::searchJourneyLater() } currentRequestState = FahrplanNS::searchJourneyLaterRequest; + clearJourney(); internalSearchJourney(lastJourneySearch.from, lastJourneySearch.via, lastJourneySearch.to, time, lastJourneySearch.mode, lastJourneySearch.restrictions); } @@ -280,6 +284,7 @@ void ParserResRobot::searchJourneyEarlier() } currentRequestState = FahrplanNS::searchJourneyEarlierRequest; + clearJourney(); internalSearchJourney(lastJourneySearch.from, lastJourneySearch.via, lastJourneySearch.to, time, lastJourneySearch.mode, lastJourneySearch.restrictions); } @@ -472,7 +477,6 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) journeyListData = ensureList(timetableResult.value("ttitem")); } - clearJourney(); lastJourneyResultList = new JourneyResultList(this); int journeyCounter = 0; diff --git a/src/parser/parser_xmlvasttrafikse.cpp b/src/parser/parser_xmlvasttrafikse.cpp index f2c699cd..cf2190b5 100644 --- a/src/parser/parser_xmlvasttrafikse.cpp +++ b/src/parser/parser_xmlvasttrafikse.cpp @@ -160,6 +160,8 @@ void ParserXmlVasttrafikSe::searchJourney(const Station &departureStation, const return; currentRequestState = FahrplanNS::searchJourneyRequest; + clearJourney(); + m_searchJourneyParameters.isValid = false; m_searchJourneyParameters.departureStation = departureStation; m_searchJourneyParameters.arrivalStation = arrivalStation; @@ -323,7 +325,6 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) { qDebug() << "ParserXmlVasttrafikSe::parseSearchJourney(networkReply.url()=" << networkReply->url().toString() << ")"; - clearJourney(); lastJourneyResultList = new JourneyResultList(this); /// Use fallback values for empty results (i.e. no connections found) From 7c557111e1bdb63a2e878e6e785ac3f0d1bd252d Mon Sep 17 00:00:00 2001 From: Thomas Fischer Date: Sat, 30 Jul 2016 00:27:16 +0200 Subject: [PATCH 59/85] Adding RMV.de for southern/central Hesse, Germany Adding support for Rhein-Main-Verkehrsverbund (RMV), the transport network serving the Frankfurt metropolitan area in southern and central Hesse, Germany. The implementation is actually quite simple, as RMV uses HAFAS, inheriting and specializing the existing ParserHafasXml class. --- fahrplan2.pro | 2 ++ src/fahrplan_backend_manager.cpp | 1 + src/fahrplan_parser_thread.cpp | 3 +++ src/fahrplan_parser_thread.h | 1 + src/parser/parser_xmlrmvde.cpp | 31 ++++++++++++++++++++++++ src/parser/parser_xmlrmvde.h | 41 ++++++++++++++++++++++++++++++++ 6 files changed, 79 insertions(+) create mode 100644 src/parser/parser_xmlrmvde.cpp create mode 100644 src/parser/parser_xmlrmvde.h diff --git a/fahrplan2.pro b/fahrplan2.pro index 9a3475a3..0fdb3a50 100644 --- a/fahrplan2.pro +++ b/fahrplan2.pro @@ -124,6 +124,7 @@ HEADERS += \ src/parser/parser_salzburg_efa.h \ src/parser/parser_resrobot.h \ src/parser/parser_finland_matka.h \ + src/parser/parser_xmlrmvde.h \ src/models/backends.h SOURCES += src/main.cpp \ src/parser/parser_hafasxml.cpp \ @@ -157,6 +158,7 @@ SOURCES += src/main.cpp \ src/parser/parser_salzburg_efa.cpp \ src/parser/parser_resrobot.cpp \ src/parser/parser_finland_matka.cpp \ + src/parser/parser_xmlrmvde.cpp \ src/models/backends.cpp LIBS += $$PWD/3rdparty/gauss-kruger-cpp/gausskruger.cpp diff --git a/src/fahrplan_backend_manager.cpp b/src/fahrplan_backend_manager.cpp index 6831aab0..9a6b0fa3 100644 --- a/src/fahrplan_backend_manager.cpp +++ b/src/fahrplan_backend_manager.cpp @@ -45,6 +45,7 @@ QStringList FahrplanBackendManager::getParserList() result.append(ParserSalzburgEFA::getName()); result.append(ParserResRobot::getName()); result.append(ParserFinlandMatka::getName()); + result.append(ParserXmlRMVde::getName()); // Make sure the index is in bounds if (currentParserIndex > (result.count() - 1) || currentParserIndex < 0) { diff --git a/src/fahrplan_parser_thread.cpp b/src/fahrplan_parser_thread.cpp index 599ed2b5..7069edae 100644 --- a/src/fahrplan_parser_thread.cpp +++ b/src/fahrplan_parser_thread.cpp @@ -170,6 +170,9 @@ void FahrplanParserThread::run() case 15: m_parser = new ParserFinlandMatka(); break; + case 16: + m_parser = new ParserXmlRMVde(); + break; } m_name = m_parser->name(); diff --git a/src/fahrplan_parser_thread.h b/src/fahrplan_parser_thread.h index 4ede6256..5df52040 100644 --- a/src/fahrplan_parser_thread.h +++ b/src/fahrplan_parser_thread.h @@ -40,6 +40,7 @@ #include "parser/parser_salzburg_efa.h" #include "parser/parser_resrobot.h" #include "parser/parser_finland_matka.h" +#include "parser/parser_xmlrmvde.h" class FahrplanParserThread : public QThread { diff --git a/src/parser/parser_xmlrmvde.cpp b/src/parser/parser_xmlrmvde.cpp new file mode 100644 index 00000000..76cadd54 --- /dev/null +++ b/src/parser/parser_xmlrmvde.cpp @@ -0,0 +1,31 @@ +#include "parser_xmlrmvde.h" + +#include + +ParserXmlRMVde::ParserXmlRMVde(QObject *parent) : + ParserHafasXml(parent) +{ + baseXmlUrl = QLatin1String("http://www.rmv.de/auskunft/bin/jp/query.exe"); + baseUrl = QLatin1String("http://www.rmv.de/auskunft/bin/jp/query.exe"); +} + +void ParserXmlRMVde::parseStationsByName(QNetworkReply *networkReply) +{ + const QString data = QString::fromUtf8(networkReply->readAll()); + const StationsList result = internalParseStationsByName(data); + emit stationsResult(result); +} + +QString ParserXmlRMVde::getTrainRestrictionsCodes(int trainrestrictions) +{ + Q_UNUSED(trainrestrictions) + // TODO should something else get returned? + return "1111111111111111"; +} + +QStringList ParserXmlRMVde::getTrainRestrictions() +{ + QStringList result; + result.append(tr("All")); + return result; +} diff --git a/src/parser/parser_xmlrmvde.h b/src/parser/parser_xmlrmvde.h new file mode 100644 index 00000000..38bd663a --- /dev/null +++ b/src/parser/parser_xmlrmvde.h @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** This file is a part of Fahrplan. +** +** 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 2 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 PARSER_XMLRMVDE_H +#define PARSER_XMLRMVDE_H + +#include "parser_hafasxml.h" + +class ParserXmlRMVde : public ParserHafasXml +{ + Q_OBJECT + +public: + explicit ParserXmlRMVde(QObject *parent = 0); + static QString getName() { return QString(QLatin1String("%1 (rmv.de)")).arg(tr("Germany, Hesse")); } + virtual QString name() { return getName(); } + virtual QString shortName() { return QLatin1String("rmv.de"); } + +protected: + void parseStationsByName(QNetworkReply *networkReply); + QStringList getTrainRestrictions(); + QString getTrainRestrictionsCodes(int trainrestrictions); +}; + +#endif // PARSER_XMLRMVDE_H From 0290d60841328e46cfecb6f65c67e120f67f6243 Mon Sep 17 00:00:00 2001 From: Chris Clime Date: Sat, 13 Jan 2018 23:26:19 +0100 Subject: [PATCH 60/85] start london prototype --- fahrplan2.pro | 2 + src/fahrplan_backend_manager.cpp | 1 + src/fahrplan_parser_thread.cpp | 3 + src/fahrplan_parser_thread.h | 1 + src/parser/parser_london_tfl.cpp | 536 +++++++++++++++++++++++++++++++ src/parser/parser_london_tfl.h | 98 ++++++ 6 files changed, 641 insertions(+) create mode 100644 src/parser/parser_london_tfl.cpp create mode 100644 src/parser/parser_london_tfl.h diff --git a/fahrplan2.pro b/fahrplan2.pro index 1bf931a2..083d1bbc 100644 --- a/fahrplan2.pro +++ b/fahrplan2.pro @@ -129,6 +129,7 @@ HEADERS += \ src/parser/parser_salzburg_efa.h \ src/parser/parser_resrobot.h \ src/parser/parser_finland_matka.h \ + src/parser/parser_london_tfl.h \ src/models/backends.h SOURCES += src/main.cpp \ @@ -163,6 +164,7 @@ SOURCES += src/main.cpp \ src/parser/parser_salzburg_efa.cpp \ src/parser/parser_resrobot.cpp \ src/parser/parser_finland_matka.cpp \ + src/parser/parser_london_tfl.cpp \ src/models/backends.cpp LIBS += $$PWD/3rdparty/gauss-kruger-cpp/gausskruger.cpp diff --git a/src/fahrplan_backend_manager.cpp b/src/fahrplan_backend_manager.cpp index 6831aab0..e76dd84d 100644 --- a/src/fahrplan_backend_manager.cpp +++ b/src/fahrplan_backend_manager.cpp @@ -45,6 +45,7 @@ QStringList FahrplanBackendManager::getParserList() result.append(ParserSalzburgEFA::getName()); result.append(ParserResRobot::getName()); result.append(ParserFinlandMatka::getName()); + result.append(ParserLondonTfl::getName()); // Make sure the index is in bounds if (currentParserIndex > (result.count() - 1) || currentParserIndex < 0) { diff --git a/src/fahrplan_parser_thread.cpp b/src/fahrplan_parser_thread.cpp index 599ed2b5..c759fad7 100644 --- a/src/fahrplan_parser_thread.cpp +++ b/src/fahrplan_parser_thread.cpp @@ -170,6 +170,9 @@ void FahrplanParserThread::run() case 15: m_parser = new ParserFinlandMatka(); break; + case 16: + m_parser = new ParserLondonTfl(); + break; } m_name = m_parser->name(); diff --git a/src/fahrplan_parser_thread.h b/src/fahrplan_parser_thread.h index 4ede6256..3f32624e 100644 --- a/src/fahrplan_parser_thread.h +++ b/src/fahrplan_parser_thread.h @@ -40,6 +40,7 @@ #include "parser/parser_salzburg_efa.h" #include "parser/parser_resrobot.h" #include "parser/parser_finland_matka.h" +#include "parser/parser_london_tfl.h" class FahrplanParserThread : public QThread { diff --git a/src/parser/parser_london_tfl.cpp b/src/parser/parser_london_tfl.cpp new file mode 100644 index 00000000..9bef100b --- /dev/null +++ b/src/parser/parser_london_tfl.cpp @@ -0,0 +1,536 @@ +/**************************************************************************** +** +** This file is a part of Fahrplan. +** +** 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 2 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 "parser_london_tfl.h" + +#include +#include +#ifdef BUILD_FOR_QT5 +# include +#else +# define setQuery(q) setQueryItems(q.queryItems()) +#endif +#include + +namespace +{ + const QUrl BaseUrl("https://api.tfl.gov.uk"); +} + +//inline qreal deg2rad(qreal deg) +//{ +// return deg * 3.141592653589793238463 / 180; +//} + +/* +inline int distance(qreal lat1, qreal lon1, qreal lat2, qreal lon2) +{ + const qreal sdLat = qSin(deg2rad(lat2 - lat1) / 2); + const qreal sdLon = qSin(deg2rad(lon2 - lon1) / 2); + const qreal cLat1 = qCos(deg2rad(lat1)); + const qreal cLat2 = qCos(deg2rad(lat2)); + const qreal a = sdLat * sdLat + sdLon * sdLon * cLat1 * cLat2; + const qreal c = 2 * qAtan2(qSqrt(a), qSqrt(1 - a)); + + // 6371 km - Earth radius. + // We return distance in meters, thus * 1000. + return qRound(6371.0 * c * 1000); +} +*/ + +ParserLondonTfl::ParserLondonTfl(QObject *parent):ParserAbstract(parent) +{ + lastCoordinates.isValid = false; +} + +void ParserLondonTfl::getTimeTableForStation(const Station ¤tStation, + const Station &, + const QDateTime &, + ParserAbstract::Mode, + int trainrestrictions) +{ + QUrl relativeUri(QString("/locations/%1/departure-times").arg(currentStation.id.toString())); + +#if defined(BUILD_FOR_QT5) + QUrlQuery query; +#else + QUrl query; +#endif + + query.addQueryItem("lang", "en-GB"); + relativeUri.setQuery(query); + + timetableRestrictions = trainrestrictions; + sendHttpRequest(BaseUrl.resolved(relativeUri)); + currentRequestState=FahrplanNS::getTimeTableForStationRequest; +} + +void ParserLondonTfl::findStationsByName(const QString &stationName) +{ + qDebug() << "FINDBYNAME"; + QUrl relativeUrl (QString("/Stoppoint/Search/%1").arg(stationName)); + + QUrl uri(BaseUrl.resolved(relativeUrl)); + + /* +#if defined(BUILD_FOR_QT5) + QUrlQuery query; +#else + QUrl query; +#endif + query.addQueryItem("lang", "en-GB"); + query.addQueryItem("q", stationName); + uri.setQuery(query); + */ + + sendHttpRequest(uri); + currentRequestState=FahrplanNS::stationsByNameRequest; +} + +void ParserLondonTfl::findStationsByCoordinates(qreal longitude, qreal latitude) +{ + return; + + QUrl uri(BaseUrl); + //QUrl uri(BASE_URL "locations"); + +#if defined(BUILD_FOR_QT5) + QUrlQuery query; +#else + QUrl query; +#endif + query.addQueryItem("lang", "en-GB"); + query.addQueryItem("type", "station,stop"); + query.addQueryItem("latlong", QString("%1,%2").arg(latitude).arg(longitude)); + query.addQueryItem("includestation", "true"); + uri.setQuery(query); + + lastCoordinates.isValid = true; + lastCoordinates.latitude = latitude; + lastCoordinates.longitude = longitude; + currentRequestState = FahrplanNS::stationsByCoordinatesRequest; + + sendHttpRequest(uri); +} + +void ParserLondonTfl::searchJourney(const Station &departureStation, + const Station &viaStation, + const Station &arrivalStation, + const QDateTime &dateTime, + const ParserAbstract::Mode mode, + int trainrestrictions) +{ + lastsearch.from=departureStation; + lastsearch.to=arrivalStation; + lastsearch.restrictions=trainrestrictions; + lastsearch.via=viaStation; + + QUrl relativeUri(QString("Journey/Journeyresults/%1/to/%2").arg(departureStation.id.toString(), arrivalStation.id.toString())); + +#if defined(BUILD_FOR_QT5) + QUrlQuery query; +#else + QUrl query; +#endif + + /* + query.addQueryItem("lang", "en-GB"); + query.addQueryItem("before", "1"); + query.addQueryItem("from", departureStation.id.toString()); + if(viaStation.valid) + query.addQueryItem("via", viaStation.id.toString()); + query.addQueryItem("to", arrivalStation.id.toString()); + query.addQueryItem("sequence", "1"); + query.addQueryItem("dateTime", dateTime.toString("yyyy-MM-ddTHHmm")); + + switch(trainrestrictions){ + default: + case all: + query.addQueryItem("byFerry", "true"); + case noFerry: + query.addQueryItem("byBus", "true"); + query.addQueryItem("byTram", "true"); + query.addQueryItem("bySubway", "true"); + case trainsOnly: + query.addQueryItem("byTrain", "true"); + } + query.addQueryItem("searchtype", mode==Departure?"departure":"arrival"); + + //TODO: make transport types work + query.addQueryItem("after", "5"); + + uri.setQuery(query); + sendHttpRequest(uri); + + */ + + relativeUri.setQuery(query); + sendHttpRequest(BaseUrl.resolved(relativeUri)); + + currentRequestState=FahrplanNS::searchJourneyRequest; +} + +void ParserLondonTfl::searchJourneyLater() +{ + searchJourney(lastsearch.from, lastsearch.via, lastsearch.to, lastsearch.lastOption, Departure , lastsearch.restrictions); + +} + +void ParserLondonTfl::searchJourneyEarlier() +{ + QDateTime time = lastsearch.firstOption.addSecs(-30*60); + searchJourney(lastsearch.from, lastsearch.via, lastsearch.to,time, Departure, lastsearch.restrictions); +} + +void ParserLondonTfl::getJourneyDetails(const QString &id) +{ + if(cachedResults.contains(id)) + emit journeyDetailsResult(cachedResults.value(id)); +} + +QStringList ParserLondonTfl::getTrainRestrictions() +{ + QStringList restrictions; + restrictions << tr("All"); + restrictions << tr("Only trains"); + restrictions << tr("All, except ferry"); + return restrictions; +} + +/* +bool sortByTimeLessThan(const TimetableEntry &first, const TimetableEntry &second) +{ + if (first.time == second.time) + return first.trainType < second.trainType; + else + return first.time < second.time; +} +*/ + +void ParserLondonTfl::parseTimeTable(QNetworkReply *networkReply) +{ + return; + + TimetableEntriesList result; + QByteArray allData = networkReply->readAll(); +// qDebug() << "REPLY:>>>>>>>>>>>>\n" << allData; + + QVariantMap doc = parseJson(allData); + if (doc.isEmpty()) { + emit errorOccured(tr("Cannot parse reply from the server")); + return; + } + + QVariantList tabs = doc.value("tabs").toList(); + QString currentStation(doc.value("location").toMap().value("name").toString()); + + QVariantList::const_iterator i; + for (i = tabs.constBegin(); i != tabs.constEnd(); ++i) { + QVariantMap tab = i->toMap(); + QString type = tab.value("id").toString(); + QVariantList departures = tab.value("departures").toList(); + switch(timetableRestrictions){ + case all: + default: + break; + case trainsOnly: + if(type!="train") + continue; + break; + case noFerry: + if(type=="ferry")//not sure if this ever happens + continue; + break; + } + + QVariantList::const_iterator j; + for (j = departures.constBegin(); j != departures.constEnd(); ++j) { + QVariantMap departure = j->toMap(); + TimetableEntry entry; + entry.currentStation=currentStation; + entry.destinationStation = departure.value("destinationName").toString(); + entry.time = QTime::fromString(departure.value("time").toString(), "HH:mm"); + QString via(departure.value("viaNames").toString()); + if (!via.isEmpty()) + entry.destinationStation = tr("%1 via %2").arg(entry.destinationStation, via); + QStringList info; + const QString rtStatus = departure.value("realtimeState").toString(); + if (rtStatus == "ontime") { + info << tr("On-Time"); + } else if (rtStatus == "late") { + const QString rtMessage = departure.value("realtimeText").toString().trimmed(); + if (!rtMessage.isEmpty()) + info << QString("%1").arg(rtMessage); + } + const QString remark = departure.value("remark").toString(); + if (!remark.isEmpty()) + info << remark; + entry.miscInfo = info.join("
"); + + entry.platform = departure.value("platform").toString(); + + QString train = departure.value("mode").toMap().value("name").toString(); + const QString service = departure.value("service").toString(); + if (!service.isEmpty()) + train.append(" ").append(service); + entry.trainType = train; + + result.append(entry); + } + } + + // Departures / arrivals are grouped by transportation type, + // while we want them sorted by departure / arrival time. + //qSort(result.begin(), result.end(), sortByTimeLessThan); + + emit timetableResult(result); + +} + +void ParserLondonTfl::parseStationsByName(QNetworkReply *networkReply) +{ + qDebug() << "PARSING STATIONS"; + QByteArray allData = networkReply->readAll(); + qDebug() << "REPLY:>>>>>>>>>>>>\n" << allData; + + QVariantMap doc = parseJson(allData); + if (doc.isEmpty()) { + emit errorOccured(tr("Cannot parse reply from the server")); + return; + } + + QVariantList stations = doc.value("matches").toList(); + + StationsList result; + + QVariantList::const_iterator i; + for (i = stations.constBegin(); i != stations.constEnd(); ++i) { + QVariantMap station = i->toMap(); + Station s; + s.id = station.value("icsId"); + s.name = station.value("name").toString(); + s.latitude = station.value("lat").toDouble(); + s.longitude = station.value("lon").toDouble(); + s.miscInfo = "Zone " + station.value("zone").toString(); + result.append(s); + } + + emit stationsResult(result); +} + +void ParserLondonTfl::parseStationsByCoordinates(QNetworkReply *networkReply) +{ + return; + + parseStationsByName(networkReply); + + lastCoordinates.isValid = false; +} + +void ParserLondonTfl::parseSearchJourney(QNetworkReply *networkReply) +{ + // baker street to great portland street + //https://api.tfl.gov.uk/Journey/Journeyresults/1000011/to/1000091 + + qDebug() << "PARSING JOURNEYS"; + QByteArray allData = networkReply->readAll(); + qDebug() << "REPLY:>>>>>>>>>>>>\n" << allData; + + QVariantMap doc = parseJson(allData); + if (doc.isEmpty()) { + emit errorOccured(tr("Cannot parse reply from the server")); + return; + } + + QVariantList journeys = doc.value("journeys").toList(); + + JourneyResultList* result=new JourneyResultList; + + QDateTime arrival; + QDateTime departure; + + QVariantList::const_iterator i; + for (i = journeys.constBegin(); i != journeys.constEnd(); ++i) { + QVariantMap journey = i->toMap(); + parseJourneyOption(journey); + JourneyResultItem* item = new JourneyResultItem; + arrival = QDateTime::fromString(journey.value("arrivalDateTime").toString()); + departure = QDateTime::fromString(journey.value("startDateTime").toString()); + + if (i == journeys.constBegin()) + lastsearch.firstOption=departure; + + item->setArrivalTime(arrival.toString("HH:mm")); + item->setDepartureTime(departure.toString("HH:mm")); + + QVariantList legs = journey.value("legs").toList(); + QStringList trains; + + QVariantList::const_iterator j; + for (j = legs.constBegin(); j != legs.constEnd(); ++j) + { + const QVariantMap mode = j->toMap().value("mode").toMap(); + if (mode.value("type").toString() != "walk") { + const QString typeName = mode.value("name").toString(); + if (!typeName.isEmpty()) + trains.append(typeName); + } + } + + trains.removeDuplicates(); + + item->setTrainType(trains.join(", ").trimmed()); + + //item->setTransfers(QString::number((int) journey.value("numberOfChanges").toDouble())); + item->setTransfers(QString::number(legs.count())); + + int minutes = departure.secsTo(arrival)/60; + item->setDuration(QString("%1:%2").arg(minutes/60).arg(minutes%60,2,10,QChar('0'))); + item->setId(journey.value("id").toString()); + result->appendItem(item); + + //Set result metadata based on first result + if (result->itemcount() == 1) { + result->setTimeInfo(arrival.date().toString()); + result->setDepartureStation(cachedResults[item->id()]->departureStation()); + result->setArrivalStation(cachedResults[item->id()]->arrivalStation()); + } + } + lastsearch.lastOption=departure; + emit journeyResult(result); +} + +void ParserLondonTfl::parseSearchLaterJourney(QNetworkReply *) +{ + +} + +void ParserLondonTfl::parseSearchEarlierJourney(QNetworkReply *) +{ + +} + +void ParserLondonTfl::parseJourneyDetails(QNetworkReply *) +{ + //should never happen +} + +void ParserLondonTfl::parseJourneyOption(const QVariantMap &object) +{ + JourneyDetailResultList* result = new JourneyDetailResultList; + + //QString id = object.value("id").toString(); + + QString id = QDateTime().toString(); + + QVariantList legs = object.value("legs").toList(); + + QDateTime arrival = QDateTime::fromString(object.value("arrivalDateTime").toString()); + QDateTime departure = QDateTime::fromString(object.value("startDateTime").toString()); + result->setArrivalDateTime(arrival); + result->setDepartureDateTime(departure); + int minutes=departure.secsTo(arrival)/60; + int hours=minutes/60; + minutes=minutes%60; + result->setDuration(QString("%1:%2").arg(hours).arg(minutes, 2, 10, QChar('0'))); + //result->setId(id); + + for(int i = 0; i < legs.count(); i++) + { + QVariantMap leg = legs.at(i).toMap(); + JourneyDetailResultItem* resultItem = new JourneyDetailResultItem; + + QVariantMap firstStop = leg["departurePoint"].toMap(); + QVariantMap lastStop = leg["arrivalPoint"].toMap(); + + resultItem->setDepartureDateTime(QDateTime::fromString(leg.value("departureTime").toString())); + resultItem->setArrivalDateTime(QDateTime::fromString(leg.value("arrivalTime").toString())); + resultItem->setDepartureStation(firstStop.value("commonName").toString()); + resultItem->setArrivalStation(lastStop.value("commonName").toString()); + + /* + QVariantList stops = leg.value("stops").toList(); + + + QVariantMap firstStop = stops[0].toMap(); + QVariantMap lastStop = stops[stops.size()-1].toMap(); + QVariantMap firstLocation = firstStop.value("location").toMap(); + QVariantMap lastLocation = lastStop.value("location").toMap(); + + resultItem->setArrivalStation(lastLocation.value("name").toString()); + resultItem->setDepartureStation(firstLocation.value("name").toString()); + + QDateTime stopDeparture = QDateTime::fromString(firstStop.value("departure").toString(), + "yyyy-MM-ddTHH:mm"); + QDateTime stopArrival = QDateTime::fromString(lastStop.value("arrival").toString(), + "yyyy-MM-ddTHH:mm"); + + resultItem->setDepartureDateTime(stopDeparture); + resultItem->setArrivalDateTime(stopArrival); + + */ + + QString type = leg.value("mode").toMap().value("type").toString(); + QString typeName; + if (type != "walk") + typeName = leg.value("mode").toMap().value("name").toString(); + + //Fallback if typeName is empty + if (typeName.isEmpty() && !type.isEmpty()) { + typeName = type; + typeName[0] = type.at(0).toUpper(); + } + + const QString service = leg.value("service").toString(); + if (!service.isEmpty()) + typeName.append(" ").append(service); + + if (type == "walk") { + const QString duration = leg.value("duration").toString(); + resultItem->setTrain(tr("%1 for %2 min").arg(typeName, duration)); + } else { + resultItem->setTrain(typeName); + } + + /* + if (!firstStop.value("platform").toString().isEmpty()) { + resultItem->setDepartureInfo(tr("Pl. %1").arg(firstStop.value("platform").toString())); + } + if (!lastStop.value("platform").toString().isEmpty()) { + resultItem->setArrivalInfo(tr("Pl. %1").arg(lastStop.value("platform").toString())); + } + */ + + //resultItem->setDirection(leg.value("destination").toString()); + + QStringList attributes; + const QVariantList attrs = leg.value("attributes").toList(); + foreach (const QVariant &attr, attrs) { + attributes << attr.toMap().value("title").toString(); + } + resultItem->setInfo(attributes.join(tr(", "))); + + result->appendItem(resultItem); + } + + result->setDepartureStation(result->getItem(0)->departureStation()); + result->setArrivalStation(result->getItem(result->itemcount() - 1)->arrivalStation()); + + cachedResults.insert(id, result); +} diff --git a/src/parser/parser_london_tfl.h b/src/parser/parser_london_tfl.h new file mode 100644 index 00000000..f2044ea1 --- /dev/null +++ b/src/parser/parser_london_tfl.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** This file is a part of Fahrplan. +** +** 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 2 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 PARSER_LONDONTFL_H +#define PARSER_LONDONTFL_H + +#include "parser_abstract.h" + +#include + +class QNetworkReply; +/** + * @brief The ParserNinetwo class + * Parser for the 9292ov.nl dutch public transport route planner backend. + * it uses the unofficial json backend + */ +class ParserLondonTfl : public ParserAbstract +{ + Q_OBJECT + struct { + QDateTime firstOption; + QDateTime lastOption; + Station from; + Station via; + Station to; + int restrictions; + Mode mode; + + } lastsearch; + + struct { + bool isValid; + qreal latitude; + qreal longitude; + } lastCoordinates; + + typedef enum restrictions{ + all=0, + trainsOnly=1, + noFerry=2 + } restrictions; + + int timetableRestrictions; + +public: + ParserLondonTfl(QObject* parent = 0); + + // ParserAbstract interface +public: + static QString getName() { return QString("%1 (tfl.gov.uk)").arg(tr("London")); } + virtual QString name() { return getName(); } + virtual QString shortName() { return "Transport for London"; } + +public slots: + void getTimeTableForStation(const Station ¤tStation, const Station &directionStation, const QDateTime &dateTtime, ParserAbstract::Mode mode, int trainrestrictions); + void findStationsByName(const QString &stationName); + void findStationsByCoordinates(qreal longitude, qreal latitude); + void searchJourney(const Station &departureStation,const Station &viaStation,const Station &arrivalStation,const QDateTime &dateTime,const ParserAbstract::Mode mode, int trainrestrictions); + void searchJourneyLater(); + void searchJourneyEarlier(); + void getJourneyDetails(const QString &id); + bool supportsGps() { return true; } + bool supportsVia() { return true; } + bool supportsTimeTable() { return true; } + bool supportsTimeTableDirection() { return false; } + QStringList getTrainRestrictions(); + +protected: + void parseTimeTable(QNetworkReply *networkReply); + void parseStationsByName(QNetworkReply *networkReply); + void parseStationsByCoordinates(QNetworkReply *networkReply); + void parseSearchJourney(QNetworkReply *networkReply); + void parseSearchLaterJourney(QNetworkReply *networkReply); + void parseSearchEarlierJourney(QNetworkReply *networkReply); + void parseJourneyDetails(QNetworkReply *networkReply); + QMap cachedResults; + +private: + void parseJourneyOption(const QVariantMap &object); +}; + +#endif // PARSER_LONDONTFL_H From 5847268c2c93ff02554dd67f2a36dc9bdd3dfb6a Mon Sep 17 00:00:00 2001 From: Chris Clime Date: Sun, 14 Jan 2018 20:11:56 +0100 Subject: [PATCH 61/85] continue prototyping TFL --- src/parser/parser_london_tfl.cpp | 115 ++++++++++++++++++++----------- src/parser/parser_london_tfl.h | 2 +- 2 files changed, 75 insertions(+), 42 deletions(-) diff --git a/src/parser/parser_london_tfl.cpp b/src/parser/parser_london_tfl.cpp index 9bef100b..30d43fd7 100644 --- a/src/parser/parser_london_tfl.cpp +++ b/src/parser/parser_london_tfl.cpp @@ -24,6 +24,7 @@ #ifdef BUILD_FOR_QT5 # include #else +#include # define setQuery(q) setQueryItems(q.queryItems()) #endif #include @@ -31,8 +32,17 @@ namespace { const QUrl BaseUrl("https://api.tfl.gov.uk"); + + /* + QString escapeHtmlChars(const QString & input) + { + + } + */ } +//QHash cachedJourneyDetailsTfl; + //inline qreal deg2rad(qreal deg) //{ // return deg * 3.141592653589793238463 / 180; @@ -366,12 +376,16 @@ void ParserLondonTfl::parseSearchJourney(QNetworkReply *networkReply) QDateTime departure; QVariantList::const_iterator i; + int counter = 0; + for (i = journeys.constBegin(); i != journeys.constEnd(); ++i) { + counter++; QVariantMap journey = i->toMap(); - parseJourneyOption(journey); + QString id = QString::number(counter); + parseJourneyOption(journey, id); JourneyResultItem* item = new JourneyResultItem; - arrival = QDateTime::fromString(journey.value("arrivalDateTime").toString()); - departure = QDateTime::fromString(journey.value("startDateTime").toString()); + arrival = QDateTime::fromString(journey.value("arrivalDateTime").toString(), "yyyy-MM-ddTHH:mm:ss"); + departure = QDateTime::fromString(journey.value("startDateTime").toString(), "yyyy-MM-ddTHH:mm:ss"); if (i == journeys.constBegin()) lastsearch.firstOption=departure; @@ -386,7 +400,7 @@ void ParserLondonTfl::parseSearchJourney(QNetworkReply *networkReply) for (j = legs.constBegin(); j != legs.constEnd(); ++j) { const QVariantMap mode = j->toMap().value("mode").toMap(); - if (mode.value("type").toString() != "walk") { + if (mode.value("type").toString() != "walking") { const QString typeName = mode.value("name").toString(); if (!typeName.isEmpty()) trains.append(typeName); @@ -398,11 +412,15 @@ void ParserLondonTfl::parseSearchJourney(QNetworkReply *networkReply) item->setTrainType(trains.join(", ").trimmed()); //item->setTransfers(QString::number((int) journey.value("numberOfChanges").toDouble())); - item->setTransfers(QString::number(legs.count())); + item->setTransfers(QString::number(legs.count() - 1)); int minutes = departure.secsTo(arrival)/60; item->setDuration(QString("%1:%2").arg(minutes/60).arg(minutes%60,2,10,QChar('0'))); - item->setId(journey.value("id").toString()); + + //item->setId(journey.value("id").toString()); + //item->setId(randString(10)); + item->setId(id); + result->appendItem(item); //Set result metadata based on first result @@ -431,25 +449,22 @@ void ParserLondonTfl::parseJourneyDetails(QNetworkReply *) //should never happen } -void ParserLondonTfl::parseJourneyOption(const QVariantMap &object) +void ParserLondonTfl::parseJourneyOption(const QVariantMap &object, const QString &id) { JourneyDetailResultList* result = new JourneyDetailResultList; - //QString id = object.value("id").toString(); - - QString id = QDateTime().toString(); - QVariantList legs = object.value("legs").toList(); - QDateTime arrival = QDateTime::fromString(object.value("arrivalDateTime").toString()); - QDateTime departure = QDateTime::fromString(object.value("startDateTime").toString()); + QDateTime arrival = QDateTime::fromString(object.value("arrivalDateTime").toString(), "yyyy-MM-ddTHH:mm:ss"); + QDateTime departure = QDateTime::fromString(object.value("startDateTime").toString(), "yyyy-MM-ddTHH:mm:ss"); result->setArrivalDateTime(arrival); result->setDepartureDateTime(departure); int minutes=departure.secsTo(arrival)/60; int hours=minutes/60; minutes=minutes%60; result->setDuration(QString("%1:%2").arg(hours).arg(minutes, 2, 10, QChar('0'))); - //result->setId(id); + + result->setId(id); for(int i = 0; i < legs.count(); i++) { @@ -461,34 +476,13 @@ void ParserLondonTfl::parseJourneyOption(const QVariantMap &object) resultItem->setDepartureDateTime(QDateTime::fromString(leg.value("departureTime").toString())); resultItem->setArrivalDateTime(QDateTime::fromString(leg.value("arrivalTime").toString())); - resultItem->setDepartureStation(firstStop.value("commonName").toString()); - resultItem->setArrivalStation(lastStop.value("commonName").toString()); - - /* - QVariantList stops = leg.value("stops").toList(); - - - QVariantMap firstStop = stops[0].toMap(); - QVariantMap lastStop = stops[stops.size()-1].toMap(); - QVariantMap firstLocation = firstStop.value("location").toMap(); - QVariantMap lastLocation = lastStop.value("location").toMap(); - - resultItem->setArrivalStation(lastLocation.value("name").toString()); - resultItem->setDepartureStation(firstLocation.value("name").toString()); - - QDateTime stopDeparture = QDateTime::fromString(firstStop.value("departure").toString(), - "yyyy-MM-ddTHH:mm"); - QDateTime stopArrival = QDateTime::fromString(lastStop.value("arrival").toString(), - "yyyy-MM-ddTHH:mm"); - - resultItem->setDepartureDateTime(stopDeparture); - resultItem->setArrivalDateTime(stopArrival); + resultItem->setDepartureStation(firstStop.value("commonName").toString().replace("Underground Station", "πŸš‡")); + resultItem->setArrivalStation(lastStop.value("commonName").toString().replace("Underground Station", "πŸš‡")); - */ + QString type = leg.value("mode").toMap().value("name").toString(); - QString type = leg.value("mode").toMap().value("type").toString(); QString typeName; - if (type != "walk") + if (type != "walking") typeName = leg.value("mode").toMap().value("name").toString(); //Fallback if typeName is empty @@ -501,7 +495,7 @@ void ParserLondonTfl::parseJourneyOption(const QVariantMap &object) if (!service.isEmpty()) typeName.append(" ").append(service); - if (type == "walk") { + if (type == "walking") { const QString duration = leg.value("duration").toString(); resultItem->setTrain(tr("%1 for %2 min").arg(typeName, duration)); } else { @@ -512,11 +506,48 @@ void ParserLondonTfl::parseJourneyOption(const QVariantMap &object) if (!firstStop.value("platform").toString().isEmpty()) { resultItem->setDepartureInfo(tr("Pl. %1").arg(firstStop.value("platform").toString())); } + + if (!lastStop.value("platform").toString().isEmpty()) { resultItem->setArrivalInfo(tr("Pl. %1").arg(lastStop.value("platform").toString())); } */ + // get the transport options (e.g. bus or tube lines) + QVariantList stations = leg.value("routeOptions").toList(); + QStringList routeOptionsTrains; + QStringList routeOptionsDirections; + QString detailedInfo; + + QVariantList::const_iterator it_routeOpt; + for (it_routeOpt = stations.constBegin(); it_routeOpt != stations.constEnd(); ++it_routeOpt) { + + QStringList routeOptionsDirectionsCurrentTrain; + QVariantMap routeOption = it_routeOpt->toMap(); + + QString currentRouteOption = routeOption.value("name").toString().toHtmlEscaped(); + routeOptionsTrains.push_back(currentRouteOption); + detailedInfo += currentRouteOption + " to "; + + QVariantList directions = routeOption["directions"].toList(); + + QVariantList::const_iterator it_directions; + + for (it_directions = directions.constBegin(); it_directions != directions.constEnd(); ++it_directions) + { + QString currentDestination = it_directions->toString().replace("Underground Station", "").toHtmlEscaped(); + routeOptionsDirections.push_back(currentDestination); + routeOptionsDirectionsCurrentTrain.push_back(currentDestination); + } + + detailedInfo += routeOptionsDirectionsCurrentTrain.join(" or ") + ".
"; + } + + //resultItem->setTrain(routeOptionsTrains.join(",")); + resultItem->setDirection(routeOptionsDirections.join(" or ")); + + resultItem->setInfo(detailedInfo); + //resultItem->setDirection(leg.value("destination").toString()); QStringList attributes; @@ -524,7 +555,9 @@ void ParserLondonTfl::parseJourneyOption(const QVariantMap &object) foreach (const QVariant &attr, attrs) { attributes << attr.toMap().value("title").toString(); } - resultItem->setInfo(attributes.join(tr(", "))); + //resultItem->setInfo(attributes.join(tr(", "))); + + result->appendItem(resultItem); } diff --git a/src/parser/parser_london_tfl.h b/src/parser/parser_london_tfl.h index f2044ea1..d4114c77 100644 --- a/src/parser/parser_london_tfl.h +++ b/src/parser/parser_london_tfl.h @@ -92,7 +92,7 @@ public slots: QMap cachedResults; private: - void parseJourneyOption(const QVariantMap &object); + void parseJourneyOption(const QVariantMap &object, const QString & id); }; #endif // PARSER_LONDONTFL_H From 1ab48909bc4cdd97cb45cda7e32c6fdfaa1d793c Mon Sep 17 00:00:00 2001 From: Chris Clime Date: Thu, 18 Jan 2018 23:30:01 +0100 Subject: [PATCH 62/85] add stopPoint / platform info --- src/parser/parser_london_tfl.cpp | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/parser/parser_london_tfl.cpp b/src/parser/parser_london_tfl.cpp index 30d43fd7..c44521a5 100644 --- a/src/parser/parser_london_tfl.cpp +++ b/src/parser/parser_london_tfl.cpp @@ -502,16 +502,23 @@ void ParserLondonTfl::parseJourneyOption(const QVariantMap &object, const QStrin resultItem->setTrain(typeName); } - /* - if (!firstStop.value("platform").toString().isEmpty()) { - resultItem->setDepartureInfo(tr("Pl. %1").arg(firstStop.value("platform").toString())); + // stop letter / platform (departure) + if (! firstStop.value("stopLetter").toString().isEmpty()) { + resultItem->setDepartureInfo(QString("🚏 %1").arg(firstStop.value("stopLetter").toString())); } + else if (! firstStop.value("platformName").toString().isEmpty()) { + resultItem->setDepartureInfo(QString("Pl. %1").arg(firstStop.value("platformName").toString())); + } + + // stop letter / platform (arrival) + if (! lastStop.value("stopLetter").toString().isEmpty()) { + resultItem->setArrivalInfo(QString("🚏 %1").arg(lastStop.value("stopLetter").toString())); + } - if (!lastStop.value("platform").toString().isEmpty()) { - resultItem->setArrivalInfo(tr("Pl. %1").arg(lastStop.value("platform").toString())); + else if (! lastStop.value("platformName").toString().isEmpty()) { + resultItem->setArrivalInfo(QString("Pl. %1").arg(lastStop.value("platformName").toString())); } - */ // get the transport options (e.g. bus or tube lines) QVariantList stations = leg.value("routeOptions").toList(); @@ -546,7 +553,15 @@ void ParserLondonTfl::parseJourneyOption(const QVariantMap &object, const QStrin //resultItem->setTrain(routeOptionsTrains.join(",")); resultItem->setDirection(routeOptionsDirections.join(" or ")); - resultItem->setInfo(detailedInfo); + // only one train --> put it in title + if (routeOptionsTrains.count() == 1) + { + resultItem->setTrain(routeOptionsTrains[0]); + } + else + { + resultItem->setInfo(detailedInfo); + } //resultItem->setDirection(leg.value("destination").toString()); From 0001b0303858802b2daeccbf129d405d5bd7ce70 Mon Sep 17 00:00:00 2001 From: Chris Clime Date: Mon, 22 Jan 2018 20:48:45 +0100 Subject: [PATCH 63/85] add indent parameter to parser_abstract, serializeToJson --- src/parser/parser_abstract.cpp | 6 +++--- src/parser/parser_abstract.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/parser/parser_abstract.cpp b/src/parser/parser_abstract.cpp index 33d07d74..1da28763 100644 --- a/src/parser/parser_abstract.cpp +++ b/src/parser/parser_abstract.cpp @@ -168,9 +168,9 @@ QVariantMap ParserAbstract::parseJson(const QByteArray &json) const } #ifdef BUILD_FOR_QT5 -QByteArray ParserAbstract::serializeToJson(const QVariantMap& doc) const +QByteArray ParserAbstract::serializeToJson(const QVariantMap& doc, bool indent) const { - return QJsonDocument(QJsonObject::fromVariantMap(doc)).toJson(QJsonDocument::Indented); + return QJsonDocument(QJsonObject::fromVariantMap(doc)).toJson(indent ? QJsonDocument::Indented : QJsonDocument::Compact); } #else QByteArray toJson(const QVariant& value) @@ -212,7 +212,7 @@ QByteArray toJson(const QVariant& value) } } -QByteArray ParserAbstract::serializeToJson(const QVariantMap& doc) const +QByteArray ParserAbstract::serializeToJson(const QVariantMap& doc, bool indent) const { return toJson(doc); } diff --git a/src/parser/parser_abstract.h b/src/parser/parser_abstract.h index c31823ec..51ddbf00 100644 --- a/src/parser/parser_abstract.h +++ b/src/parser/parser_abstract.h @@ -93,7 +93,7 @@ protected slots: void sendHttpRequest(QUrl url, QByteArray data, const QList > &additionalHeaders = QList >()); void sendHttpRequest(QUrl url); QVariantMap parseJson(const QByteArray &data) const; - QByteArray serializeToJson(const QVariantMap &doc) const; + QByteArray serializeToJson(const QVariantMap &doc, bool indent = true) const; QByteArray gzipDecompress(QByteArray compressData); #ifdef BUILD_FOR_UBUNTU From a4885266bd803e427f9a0a60ecc8abb43ed7d746 Mon Sep 17 00:00:00 2001 From: Chris Clime Date: Mon, 22 Jan 2018 20:52:44 +0100 Subject: [PATCH 64/85] - add icsId and naptanId to configuration - add time table support and train restrictions --- src/parser/parser_london_tfl.cpp | 479 ++++++++++++++++++++----------- src/parser/parser_london_tfl.h | 20 +- 2 files changed, 324 insertions(+), 175 deletions(-) diff --git a/src/parser/parser_london_tfl.cpp b/src/parser/parser_london_tfl.cpp index c44521a5..9adb23d3 100644 --- a/src/parser/parser_london_tfl.cpp +++ b/src/parser/parser_london_tfl.cpp @@ -19,6 +19,7 @@ #include "parser_london_tfl.h" +#include #include #include #ifdef BUILD_FOR_QT5 @@ -33,40 +34,33 @@ namespace { const QUrl BaseUrl("https://api.tfl.gov.uk"); - /* - QString escapeHtmlChars(const QString & input) + const QString ModeBus = "bus"; + const QString ModeCableCar = "cable-car"; + const QString ModeCoach = "coach"; + const QString ModeDlr = "dlr"; + const QString ModeRail = "national-rail"; + const QString ModeOverground = "overground"; + const QString ModeReplacementBus = "replacement-bus"; + const QString ModeRiverBus = "river-bus"; + const QString ModeRiverTour = "river-tour"; + const QString ModeTflRail = "tflrail"; + const QString ModeTram = "tram"; + const QString ModeTube = "tube"; + + bool sortByTimeLessThan(const TimetableEntry &first, const TimetableEntry &second) { - + if (first.time == second.time) + return first.trainType < second.trainType; + else + return first.time < second.time; } - */ } -//QHash cachedJourneyDetailsTfl; - -//inline qreal deg2rad(qreal deg) -//{ -// return deg * 3.141592653589793238463 / 180; -//} - -/* -inline int distance(qreal lat1, qreal lon1, qreal lat2, qreal lon2) -{ - const qreal sdLat = qSin(deg2rad(lat2 - lat1) / 2); - const qreal sdLon = qSin(deg2rad(lon2 - lon1) / 2); - const qreal cLat1 = qCos(deg2rad(lat1)); - const qreal cLat2 = qCos(deg2rad(lat2)); - const qreal a = sdLat * sdLat + sdLon * sdLon * cLat1 * cLat2; - const qreal c = 2 * qAtan2(qSqrt(a), qSqrt(1 - a)); - - // 6371 km - Earth radius. - // We return distance in meters, thus * 1000. - return qRound(6371.0 * c * 1000); -} -*/ - ParserLondonTfl::ParserLondonTfl(QObject *parent):ParserAbstract(parent) { lastCoordinates.isValid = false; + + NetworkManagerTimeTableSubQuery = new QNetworkAccessManager(this); } void ParserLondonTfl::getTimeTableForStation(const Station ¤tStation, @@ -75,7 +69,7 @@ void ParserLondonTfl::getTimeTableForStation(const Station ¤tStation, ParserAbstract::Mode, int trainrestrictions) { - QUrl relativeUri(QString("/locations/%1/departure-times").arg(currentStation.id.toString())); + QUrl relativeUri(QString("/stoppoint/%1").arg(parseJson(currentStation.id.toByteArray()).value("naptanId").toString())); #if defined(BUILD_FOR_QT5) QUrlQuery query; @@ -83,7 +77,6 @@ void ParserLondonTfl::getTimeTableForStation(const Station ¤tStation, QUrl query; #endif - query.addQueryItem("lang", "en-GB"); relativeUri.setQuery(query); timetableRestrictions = trainrestrictions; @@ -96,20 +89,14 @@ void ParserLondonTfl::findStationsByName(const QString &stationName) qDebug() << "FINDBYNAME"; QUrl relativeUrl (QString("/Stoppoint/Search/%1").arg(stationName)); - QUrl uri(BaseUrl.resolved(relativeUrl)); - - /* #if defined(BUILD_FOR_QT5) QUrlQuery query; #else QUrl query; #endif - query.addQueryItem("lang", "en-GB"); - query.addQueryItem("q", stationName); - uri.setQuery(query); - */ + relativeUrl.setQuery(query); - sendHttpRequest(uri); + sendHttpRequest(BaseUrl.resolved(relativeUrl)); currentRequestState=FahrplanNS::stationsByNameRequest; } @@ -151,7 +138,7 @@ void ParserLondonTfl::searchJourney(const Station &departureStation, lastsearch.restrictions=trainrestrictions; lastsearch.via=viaStation; - QUrl relativeUri(QString("Journey/Journeyresults/%1/to/%2").arg(departureStation.id.toString(), arrivalStation.id.toString())); + QUrl relativeUri(QString("Journey/Journeyresults/%1/to/%2").arg(parseJson(departureStation.id.toByteArray()).value("icsId").toString(), parseJson(arrivalStation.id.toByteArray()).value("icsId").toString())); #if defined(BUILD_FOR_QT5) QUrlQuery query; @@ -159,35 +146,28 @@ void ParserLondonTfl::searchJourney(const Station &departureStation, QUrl query; #endif - /* - query.addQueryItem("lang", "en-GB"); - query.addQueryItem("before", "1"); - query.addQueryItem("from", departureStation.id.toString()); if(viaStation.valid) - query.addQueryItem("via", viaStation.id.toString()); - query.addQueryItem("to", arrivalStation.id.toString()); - query.addQueryItem("sequence", "1"); - query.addQueryItem("dateTime", dateTime.toString("yyyy-MM-ddTHHmm")); + query.addQueryItem("via", parseJson(viaStation.id.toByteArray()).value("icsId").toString()); - switch(trainrestrictions){ - default: - case all: - query.addQueryItem("byFerry", "true"); - case noFerry: - query.addQueryItem("byBus", "true"); - query.addQueryItem("byTram", "true"); - query.addQueryItem("bySubway", "true"); - case trainsOnly: - query.addQueryItem("byTrain", "true"); - } - query.addQueryItem("searchtype", mode==Departure?"departure":"arrival"); + query.addQueryItem("date", dateTime.toString("yyyyMMdd")); + query.addQueryItem("time", dateTime.toString("HHmm")); + query.addQueryItem("timeIs", (mode == Departure) ? "Departing" : "Arriving"); - //TODO: make transport types work - query.addQueryItem("after", "5"); + QStringList modesList = getModesFromTrainRestrictions(trainrestrictions); - uri.setQuery(query); - sendHttpRequest(uri); + query.addQueryItem("mode", modesList.join(',')); + /* + switch(trainrestrictions){ + case all: + break; + case bus: + query.addQueryItem("mode", "bus"); + break; + case bus_or_tube: + query.addQueryItem("mode", "bus,tube"); + break; + } */ relativeUri.setQuery(query); @@ -198,7 +178,8 @@ void ParserLondonTfl::searchJourney(const Station &departureStation, void ParserLondonTfl::searchJourneyLater() { - searchJourney(lastsearch.from, lastsearch.via, lastsearch.to, lastsearch.lastOption, Departure , lastsearch.restrictions); + QDateTime time = lastsearch.firstOption.addSecs(30*60); + searchJourney(lastsearch.from, lastsearch.via, lastsearch.to, time, Departure , lastsearch.restrictions); } @@ -218,28 +199,25 @@ QStringList ParserLondonTfl::getTrainRestrictions() { QStringList restrictions; restrictions << tr("All"); - restrictions << tr("Only trains"); - restrictions << tr("All, except ferry"); - return restrictions; -} + restrictions << tr("Nat. Rail, Tube, Overground, DLR"); + restrictions << tr("Tube, Overground, DLR"); + restrictions << tr("Bus, Tram, Tube, Overground, DLR"); + restrictions << tr("Bus, Tram"); + restrictions << tr("Bus"); + restrictions << tr("Nat. Rail"); + restrictions << tr("Tube"); + restrictions << tr("Overground"); + restrictions << tr("DLR"); -/* -bool sortByTimeLessThan(const TimetableEntry &first, const TimetableEntry &second) -{ - if (first.time == second.time) - return first.trainType < second.trainType; - else - return first.time < second.time; + return restrictions; } -*/ void ParserLondonTfl::parseTimeTable(QNetworkReply *networkReply) { - return; - - TimetableEntriesList result; + // the response contains the line groups with the stop points. + qDebug() << "PARSING STATIONS"; QByteArray allData = networkReply->readAll(); -// qDebug() << "REPLY:>>>>>>>>>>>>\n" << allData; + qDebug() << "REPLY:>>>>>>>>>>>>\n" << allData; QVariantMap doc = parseJson(allData); if (doc.isEmpty()) { @@ -247,70 +225,43 @@ void ParserLondonTfl::parseTimeTable(QNetworkReply *networkReply) return; } - QVariantList tabs = doc.value("tabs").toList(); - QString currentStation(doc.value("location").toMap().value("name").toString()); + QVariantList lineGroups = doc.value("lineGroup").toList(); + QStringList stopCodes; + + TimetableEntriesList result; + int counter; QVariantList::const_iterator i; - for (i = tabs.constBegin(); i != tabs.constEnd(); ++i) { - QVariantMap tab = i->toMap(); - QString type = tab.value("id").toString(); - QVariantList departures = tab.value("departures").toList(); - switch(timetableRestrictions){ - case all: - default: - break; - case trainsOnly: - if(type!="train") - continue; - break; - case noFerry: - if(type=="ferry")//not sure if this ever happens - continue; - break; - } + for (i = lineGroups.begin(); i != lineGroups.constEnd(); ++i) { - QVariantList::const_iterator j; - for (j = departures.constBegin(); j != departures.constEnd(); ++j) { - QVariantMap departure = j->toMap(); - TimetableEntry entry; - entry.currentStation=currentStation; - entry.destinationStation = departure.value("destinationName").toString(); - entry.time = QTime::fromString(departure.value("time").toString(), "HH:mm"); - QString via(departure.value("viaNames").toString()); - if (!via.isEmpty()) - entry.destinationStation = tr("%1 via %2").arg(entry.destinationStation, via); - QStringList info; - const QString rtStatus = departure.value("realtimeState").toString(); - if (rtStatus == "ontime") { - info << tr("On-Time"); - } else if (rtStatus == "late") { - const QString rtMessage = departure.value("realtimeText").toString().trimmed(); - if (!rtMessage.isEmpty()) - info << QString("%1").arg(rtMessage); - } - const QString remark = departure.value("remark").toString(); - if (!remark.isEmpty()) - info << remark; - entry.miscInfo = info.join("
"); + counter++; + QVariantMap lineGroup = i->toMap(); - entry.platform = departure.value("platform").toString(); + QString stopCode; + stopCode = lineGroup.value("naptanIdReference").toString(); - QString train = departure.value("mode").toMap().value("name").toString(); - const QString service = departure.value("service").toString(); - if (!service.isEmpty()) - train.append(" ").append(service); - entry.trainType = train; + if (stopCode.isEmpty()) + { + stopCode = lineGroup.value("stationAtcoCode").toString(); + } - result.append(entry); - } + if (! stopCodes.contains(stopCode)) + { + stopCodes.append(stopCode); + } + } + + QStringList::const_iterator j; + for (j = stopCodes.constBegin(); j != stopCodes.constEnd(); ++j) + { + addTimeTableEntriesOfStopPoint(*j, result); } // Departures / arrivals are grouped by transportation type, // while we want them sorted by departure / arrival time. - //qSort(result.begin(), result.end(), sortByTimeLessThan); + qSort(result.begin(), result.end(), sortByTimeLessThan); emit timetableResult(result); - } void ParserLondonTfl::parseStationsByName(QNetworkReply *networkReply) @@ -333,11 +284,20 @@ void ParserLondonTfl::parseStationsByName(QNetworkReply *networkReply) for (i = stations.constBegin(); i != stations.constEnd(); ++i) { QVariantMap station = i->toMap(); Station s; - s.id = station.value("icsId"); + + // we need to keep the icsId and the + QVariantMap idMap; + idMap["icsId"] = station.value("icsId").toString(); + idMap["naptanId"] = station.value("id").toString(); + + s.id = serializeToJson(idMap, false); s.name = station.value("name").toString(); s.latitude = station.value("lat").toDouble(); s.longitude = station.value("lon").toDouble(); - s.miscInfo = "Zone " + station.value("zone").toString(); + if (station.contains("zone")) + { + s.miscInfo = "Zone " + station.value("zone").toString(); + } result.append(s); } @@ -474,50 +434,36 @@ void ParserLondonTfl::parseJourneyOption(const QVariantMap &object, const QStrin QVariantMap firstStop = leg["departurePoint"].toMap(); QVariantMap lastStop = leg["arrivalPoint"].toMap(); - resultItem->setDepartureDateTime(QDateTime::fromString(leg.value("departureTime").toString())); - resultItem->setArrivalDateTime(QDateTime::fromString(leg.value("arrivalTime").toString())); + resultItem->setDepartureDateTime(QDateTime::fromString(leg.value("departureTime").toString(), "yyyy-MM-ddTHH:mm:ss")); + resultItem->setArrivalDateTime(QDateTime::fromString(leg.value("arrivalTime").toString(), "yyyy-MM-ddTHH:mm:ss")); resultItem->setDepartureStation(firstStop.value("commonName").toString().replace("Underground Station", "πŸš‡")); resultItem->setArrivalStation(lastStop.value("commonName").toString().replace("Underground Station", "πŸš‡")); - QString type = leg.value("mode").toMap().value("name").toString(); - - QString typeName; - if (type != "walking") - typeName = leg.value("mode").toMap().value("name").toString(); - - //Fallback if typeName is empty - if (typeName.isEmpty() && !type.isEmpty()) { - typeName = type; - typeName[0] = type.at(0).toUpper(); - } + QString mode = leg.value("mode").toMap().value("name").toString(); - const QString service = leg.value("service").toString(); - if (!service.isEmpty()) - typeName.append(" ").append(service); + //const QString service = leg.value("service").toString(); + //if (!service.isEmpty()) + // typeName.append(" ").append(service); - if (type == "walking") { - const QString duration = leg.value("duration").toString(); - resultItem->setTrain(tr("%1 for %2 min").arg(typeName, duration)); - } else { - resultItem->setTrain(typeName); - } + if (mode != "walking") { - // stop letter / platform (departure) - if (! firstStop.value("stopLetter").toString().isEmpty()) { - resultItem->setDepartureInfo(QString("🚏 %1").arg(firstStop.value("stopLetter").toString())); - } + // stop letter / platform (departure) + if (! firstStop.value("stopLetter").toString().isEmpty()) { + resultItem->setDepartureInfo(QString("🚏 %1").arg(firstStop.value("stopLetter").toString())); + } - else if (! firstStop.value("platformName").toString().isEmpty()) { - resultItem->setDepartureInfo(QString("Pl. %1").arg(firstStop.value("platformName").toString())); - } + else if (! firstStop.value("platformName").toString().isEmpty()) { + resultItem->setDepartureInfo(QString("Pl. %1").arg(firstStop.value("platformName").toString())); + } - // stop letter / platform (arrival) - if (! lastStop.value("stopLetter").toString().isEmpty()) { - resultItem->setArrivalInfo(QString("🚏 %1").arg(lastStop.value("stopLetter").toString())); - } + // stop letter / platform (arrival) + if (! lastStop.value("stopLetter").toString().isEmpty()) { + resultItem->setArrivalInfo(QString("🚏 %1").arg(lastStop.value("stopLetter").toString())); + } - else if (! lastStop.value("platformName").toString().isEmpty()) { - resultItem->setArrivalInfo(QString("Pl. %1").arg(lastStop.value("platformName").toString())); + else if (! lastStop.value("platformName").toString().isEmpty()) { + resultItem->setArrivalInfo(QString("Pl. %1").arg(lastStop.value("platformName").toString())); + } } // get the transport options (e.g. bus or tube lines) @@ -543,7 +489,12 @@ void ParserLondonTfl::parseJourneyOption(const QVariantMap &object, const QStrin for (it_directions = directions.constBegin(); it_directions != directions.constEnd(); ++it_directions) { QString currentDestination = it_directions->toString().replace("Underground Station", "").toHtmlEscaped(); - routeOptionsDirections.push_back(currentDestination); + + if (! routeOptionsDirections.contains(currentDestination)) + { + routeOptionsDirections.push_back(currentDestination); + } + routeOptionsDirectionsCurrentTrain.push_back(currentDestination); } @@ -553,13 +504,21 @@ void ParserLondonTfl::parseJourneyOption(const QVariantMap &object, const QStrin //resultItem->setTrain(routeOptionsTrains.join(",")); resultItem->setDirection(routeOptionsDirections.join(" or ")); + // walking + if (mode == "walking") + { + const QString duration = leg.value("duration").toString(); + resultItem->setTrain(tr("Walk for %2 min").arg(duration)); + } + // only one train --> put it in title - if (routeOptionsTrains.count() == 1) + else if (routeOptionsTrains.count() == 1) { resultItem->setTrain(routeOptionsTrains[0]); } else { + resultItem->setTrain(mode); resultItem->setInfo(detailedInfo); } @@ -572,8 +531,6 @@ void ParserLondonTfl::parseJourneyOption(const QVariantMap &object, const QStrin } //resultItem->setInfo(attributes.join(tr(", "))); - - result->appendItem(resultItem); } @@ -582,3 +539,181 @@ void ParserLondonTfl::parseJourneyOption(const QVariantMap &object, const QStrin cachedResults.insert(id, result); } + +QStringList ParserLondonTfl::getModesFromTrainRestrictions(int trainRestrictions) +{ + + QStringList availableModes; + + switch(trainRestrictions){ + case all: + availableModes.append(ModeBus); + availableModes.append(ModeCableCar); + availableModes.append(ModeCoach); + availableModes.append(ModeDlr); + availableModes.append(ModeRail); + availableModes.append(ModeOverground); + availableModes.append(ModeReplacementBus); + availableModes.append(ModeRiverBus); + availableModes.append(ModeRiverTour); + availableModes.append(ModeTflRail); + availableModes.append(ModeTram); + availableModes.append(ModeTube); + break; + case bus_tram_tube_overground_dlr: + availableModes.append(ModeBus); + availableModes.append(ModeTram); + availableModes.append(ModeTube); + availableModes.append(ModeOverground); + availableModes.append(ModeDlr); + break; + case rail_tube_overground_dlr: + availableModes.append(ModeRail); + availableModes.append(ModeTube); + availableModes.append(ModeOverground); + availableModes.append(ModeDlr); + break; + case tube_overground_dlr: + availableModes.append(ModeTube); + availableModes.append(ModeOverground); + availableModes.append(ModeDlr); + break; + case bus_tram: + availableModes.append(ModeBus); + availableModes.append(ModeTram); + break; + case bus: + availableModes.append(ModeBus); + break; + case rail: + availableModes.append(ModeRail); + break; + case tube: + availableModes.append(ModeTube); + break; + case overground: + availableModes.append(ModeOverground); + break; + case dlr: + availableModes.append(ModeDlr); + break; + } + + return availableModes; +} + +// check the mode +bool ParserLondonTfl::doesModeMatchTrainRestrictions(const QString & mode, int trainRestrictions) +{ + return getModesFromTrainRestrictions(trainRestrictions).contains(mode); +} + +// this is for reducing the network replies, ids not suitable for trainRestrictions are skipped +QStringList ParserLondonTfl::filterStopIdsByTrainRestrictions(const QStringList & stopIds, int trainRestrictions) +{ + QStringList output; + + QStringList::const_iterator j; + for (j = stopIds.constBegin(); j != stopIds.constEnd(); ++j) + { + QString currentId = *j; + + bool includeInFilteredOutput = true; + + bool isTubeId = (currentId.left(8) == "940GZZLU"); + bool isDlrId = (currentId.left(8) == "940GZZDL"); + bool isRailOrOverGroundId = (! isTubeId && ! isDlrId && (currentId.left(4) == "940G")); + bool isBusOrTramId = (!isTubeId && ! isDlrId && ! isRailOrOverGroundId); + + switch(trainRestrictions){ + case all: + case bus_tram_tube_overground_dlr: + break; + case rail_tube_overground_dlr: + case tube_overground_dlr: + includeInFilteredOutput = (! isBusOrTramId); + break; + case bus_tram: + case bus: + includeInFilteredOutput = isBusOrTramId; + break; + case rail: + includeInFilteredOutput = isRailOrOverGroundId; + break; + case tube: + includeInFilteredOutput = isTubeId; + break; + case overground: + includeInFilteredOutput = isRailOrOverGroundId; + break; + case dlr: + includeInFilteredOutput = isDlrId; + break; + } + + if (includeInFilteredOutput) + { + output.push_back(currentId); + } + } + + return output; +} + +#include + +void ParserLondonTfl::addTimeTableEntriesOfStopPoint(const QString & stopPointId, TimetableEntriesList & entriesList) +{ + QNetworkRequest request; + QUrl relativeUrl (QString("/Stoppoint/%1/Arrivals").arg(stopPointId)); + + request.setUrl(BaseUrl.resolved(relativeUrl)); + + QNetworkReply *networkReply = NetworkManagerTimeTableSubQuery->get(request); + + QEventLoop loop; + connect(networkReply, SIGNAL(finished()), &loop, SLOT(quit())); + loop.exec(); + + QByteArray allData = networkReply->readAll(); + // qDebug() << "REPLY:>>>>>>>>>>>>\n" << allData; + + QString filename = "/home/phablet/.config/openstore.fahrplan2/out.txt"; + QFile file(filename); + if (file.open(QIODevice::Append)) { + QTextStream stream(&file); + stream << "parseTimeTableSubQuery." << endl; + } + + + QVariantMap doc = parseJson("{ \"output\":" + allData + "}"); + + if (doc.isEmpty()) { + emit errorOccured(tr("Cannot parse reply from the server")); + return; + } + + QVariantList arrivals = doc.value("output").toList(); + + QVariantList::const_iterator i; + + for (i = arrivals.constBegin(); i != arrivals.constEnd(); ++i) { + + QVariantMap arrival = i->toMap(); + + // if the mode is not correct, we skip the value + if (! doesModeMatchTrainRestrictions(arrival.value("modeName").toString(), timetableRestrictions) ) + { + continue; + } + + TimetableEntry entry; + + entry.currentStation = arrival.value("stationName").toString(); + entry.destinationStation = arrival.value("destinationName").toString(); + entry.time = QDateTime::fromString(arrival.value("expectedArrival").toString(), "yyyy-MM-ddTHH:mm:ssZ").time(); + entry.platform = arrival.value("platformName").toString(); + entry.trainType = arrival.value("lineName").toString(); + entriesList.append(entry); + } +} diff --git a/src/parser/parser_london_tfl.h b/src/parser/parser_london_tfl.h index d4114c77..db565d1f 100644 --- a/src/parser/parser_london_tfl.h +++ b/src/parser/parser_london_tfl.h @@ -51,9 +51,16 @@ class ParserLondonTfl : public ParserAbstract } lastCoordinates; typedef enum restrictions{ - all=0, - trainsOnly=1, - noFerry=2 + all = 0, + rail_tube_overground_dlr = 1, + tube_overground_dlr = 2, + bus_tram_tube_overground_dlr = 3, + bus_tram = 4, + bus = 5, + rail = 6, + tube = 7, + overground = 8, + dlr = 9 } restrictions; int timetableRestrictions; @@ -93,6 +100,13 @@ public slots: private: void parseJourneyOption(const QVariantMap &object, const QString & id); + + QStringList getModesFromTrainRestrictions(int trainRestrictions); + bool doesModeMatchTrainRestrictions(const QString & mode, int trainRestrictions); + QStringList filterStopIdsByTrainRestrictions(const QStringList & stopIds, int trainRestrictions); + void addTimeTableEntriesOfStopPoint(const QString & stopPointId, TimetableEntriesList & entriesList); + + QNetworkAccessManager *NetworkManagerTimeTableSubQuery; }; #endif // PARSER_LONDONTFL_H From 405725b74a77b1da7b711bcb8a3349774c05a8a7 Mon Sep 17 00:00:00 2001 From: Chris Clime Date: Mon, 29 Jan 2018 20:37:04 +0100 Subject: [PATCH 65/85] work on parseStationsByCoordinates(), findStationsByCoordinates(), add shorter names for timetable train types --- src/parser/parser_london_tfl.cpp | 123 ++++++++++++++++++++++++------- 1 file changed, 96 insertions(+), 27 deletions(-) diff --git a/src/parser/parser_london_tfl.cpp b/src/parser/parser_london_tfl.cpp index 9adb23d3..ffa48a92 100644 --- a/src/parser/parser_london_tfl.cpp +++ b/src/parser/parser_london_tfl.cpp @@ -54,6 +54,21 @@ namespace else return first.time < second.time; } + + QString shortLineName(const QString & lineName) + { + QMap shortNamesMap; + + shortNamesMap["Hammersmith & City"] = "H & C"; + shortNamesMap["London Overground"] = "Overground"; + + // not found in map + if (shortNamesMap.find( lineName ) == shortNamesMap.end()) + return lineName; + + return shortNamesMap[lineName]; + + } } ParserLondonTfl::ParserLondonTfl(QObject *parent):ParserAbstract(parent) @@ -102,28 +117,29 @@ void ParserLondonTfl::findStationsByName(const QString &stationName) void ParserLondonTfl::findStationsByCoordinates(qreal longitude, qreal latitude) { - return; - - QUrl uri(BaseUrl); - //QUrl uri(BASE_URL "locations"); + QUrl relativeuri(QString("/Stoppoint")); #if defined(BUILD_FOR_QT5) QUrlQuery query; #else QUrl query; #endif - query.addQueryItem("lang", "en-GB"); - query.addQueryItem("type", "station,stop"); - query.addQueryItem("latlong", QString("%1,%2").arg(latitude).arg(longitude)); - query.addQueryItem("includestation", "true"); - uri.setQuery(query); + + longitude = -0.13556; + latitude = 51.52532; + + query.addQueryItem("lon", QString::number(longitude)); + query.addQueryItem("lat", QString::number(latitude)); + query.addQueryItem("stoptypes", "NaptanMetroStation,NaptanRailStation,NaptanBusCoachStation,NaptanFerryPort,NaptanPublicBusCoachTram"); + + relativeuri.setQuery(query); lastCoordinates.isValid = true; lastCoordinates.latitude = latitude; lastCoordinates.longitude = longitude; - currentRequestState = FahrplanNS::stationsByCoordinatesRequest; - sendHttpRequest(uri); + sendHttpRequest(BaseUrl.resolved(relativeuri)); + currentRequestState = FahrplanNS::stationsByCoordinatesRequest; } void ParserLondonTfl::searchJourney(const Station &departureStation, @@ -283,13 +299,13 @@ void ParserLondonTfl::parseStationsByName(QNetworkReply *networkReply) QVariantList::const_iterator i; for (i = stations.constBegin(); i != stations.constEnd(); ++i) { QVariantMap station = i->toMap(); - Station s; // we need to keep the icsId and the QVariantMap idMap; idMap["icsId"] = station.value("icsId").toString(); idMap["naptanId"] = station.value("id").toString(); + Station s; s.id = serializeToJson(idMap, false); s.name = station.value("name").toString(); s.latitude = station.value("lat").toDouble(); @@ -306,11 +322,74 @@ void ParserLondonTfl::parseStationsByName(QNetworkReply *networkReply) void ParserLondonTfl::parseStationsByCoordinates(QNetworkReply *networkReply) { - return; - - parseStationsByName(networkReply); + qDebug() << "PARSING STATIONS BY COORDINATES"; + QByteArray allData = networkReply->readAll(); + qDebug() << "REPLY:>>>>>>>>>>>>\n" << allData; - lastCoordinates.isValid = false; + QVariantMap doc = parseJson(allData); + if (doc.isEmpty()) { + emit errorOccured(tr("Cannot parse reply from the server")); + return; + } + + QStringList icsIds; + QVariantList stations = doc.value("stopPoints").toList(); + + StationsList result; + + QVariantList::const_iterator i; + for (i = stations.constBegin(); i != stations.constEnd(); ++i) { + QVariantMap station = i->toMap(); + + // we skip entries without icsId + if (station.value("icsCode").toString().isEmpty()) + { + continue; + } + + QString currentIcsId = station.value("icsCode").toString(); + + // we skip already found icsIds + if (icsIds.contains(currentIcsId)) + { + continue; + } + + icsIds.append(currentIcsId); + + // we need to keep the icsId and the + QVariantMap idMap; + idMap["icsId"] = currentIcsId; + idMap["naptanId"] = station.value("id").toString(); + + Station s; + s.id = serializeToJson(idMap, false); + s.name = station.value("commonName").toString(); + s.latitude = station.value("lat").toDouble(); + s.longitude = station.value("lon").toDouble(); + + QVariantList additionalProperties = station.value("additionalProperties").toList(); + + QVariantList::const_iterator j; + for (j = additionalProperties.constBegin(); j != additionalProperties.constEnd(); ++j) { + + // find the zone information + QVariantMap currentProperty = j->toMap(); + + if (currentProperty.value("key").toString() == "Zone") + { + s.miscInfo = "Zone " + currentProperty.value("value").toString(); + + // currently we do not need more info + + break; + } + } + + result.append(s); + } + + emit stationsResult(result); } void ParserLondonTfl::parseSearchJourney(QNetworkReply *networkReply) @@ -660,8 +739,6 @@ QStringList ParserLondonTfl::filterStopIdsByTrainRestrictions(const QStringList return output; } -#include - void ParserLondonTfl::addTimeTableEntriesOfStopPoint(const QString & stopPointId, TimetableEntriesList & entriesList) { QNetworkRequest request; @@ -678,14 +755,6 @@ void ParserLondonTfl::addTimeTableEntriesOfStopPoint(const QString & stopPointId QByteArray allData = networkReply->readAll(); // qDebug() << "REPLY:>>>>>>>>>>>>\n" << allData; - QString filename = "/home/phablet/.config/openstore.fahrplan2/out.txt"; - QFile file(filename); - if (file.open(QIODevice::Append)) { - QTextStream stream(&file); - stream << "parseTimeTableSubQuery." << endl; - } - - QVariantMap doc = parseJson("{ \"output\":" + allData + "}"); if (doc.isEmpty()) { @@ -713,7 +782,7 @@ void ParserLondonTfl::addTimeTableEntriesOfStopPoint(const QString & stopPointId entry.destinationStation = arrival.value("destinationName").toString(); entry.time = QDateTime::fromString(arrival.value("expectedArrival").toString(), "yyyy-MM-ddTHH:mm:ssZ").time(); entry.platform = arrival.value("platformName").toString(); - entry.trainType = arrival.value("lineName").toString(); + entry.trainType = shortLineName(arrival.value("lineName").toString()); entriesList.append(entry); } } From 70bc276cb4864aa4e40223935b4d1f5ef6255070 Mon Sep 17 00:00:00 2001 From: Chris Clime Date: Sat, 3 Feb 2018 15:23:11 +0100 Subject: [PATCH 66/85] code cleanup, use bus stop symbol --- src/parser/parser_london_tfl.cpp | 51 ++++++++++++++------------------ 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/src/parser/parser_london_tfl.cpp b/src/parser/parser_london_tfl.cpp index ffa48a92..552dd758 100644 --- a/src/parser/parser_london_tfl.cpp +++ b/src/parser/parser_london_tfl.cpp @@ -67,7 +67,14 @@ namespace return lineName; return shortNamesMap[lineName]; + } + + // e.g. replace "Underground Station" with symbol + QString shortStationName(const QString & stationName) + { + QString outputStationName = stationName; + return outputStationName.replace("Underground Station", "πŸš‡"); } } @@ -125,12 +132,14 @@ void ParserLondonTfl::findStationsByCoordinates(qreal longitude, qreal latitude) QUrl query; #endif - longitude = -0.13556; - latitude = 51.52532; + // for testing (location near Oxford Circus) + //longitude = -0.14244; + //latitude = 51.51519; query.addQueryItem("lon", QString::number(longitude)); query.addQueryItem("lat", QString::number(latitude)); query.addQueryItem("stoptypes", "NaptanMetroStation,NaptanRailStation,NaptanBusCoachStation,NaptanFerryPort,NaptanPublicBusCoachTram"); + query.addQueryItem("radius","350"); relativeuri.setQuery(query); @@ -173,19 +182,6 @@ void ParserLondonTfl::searchJourney(const Station &departureStation, query.addQueryItem("mode", modesList.join(',')); - /* - switch(trainrestrictions){ - case all: - break; - case bus: - query.addQueryItem("mode", "bus"); - break; - case bus_or_tube: - query.addQueryItem("mode", "bus,tube"); - break; - } - */ - relativeUri.setQuery(query); sendHttpRequest(BaseUrl.resolved(relativeUri)); @@ -196,7 +192,6 @@ void ParserLondonTfl::searchJourneyLater() { QDateTime time = lastsearch.firstOption.addSecs(30*60); searchJourney(lastsearch.from, lastsearch.via, lastsearch.to, time, Departure , lastsearch.restrictions); - } void ParserLondonTfl::searchJourneyEarlier() @@ -450,14 +445,11 @@ void ParserLondonTfl::parseSearchJourney(QNetworkReply *networkReply) item->setTrainType(trains.join(", ").trimmed()); - //item->setTransfers(QString::number((int) journey.value("numberOfChanges").toDouble())); item->setTransfers(QString::number(legs.count() - 1)); int minutes = departure.secsTo(arrival)/60; item->setDuration(QString("%1:%2").arg(minutes/60).arg(minutes%60,2,10,QChar('0'))); - //item->setId(journey.value("id").toString()); - //item->setId(randString(10)); item->setId(id); result->appendItem(item); @@ -515,15 +507,11 @@ void ParserLondonTfl::parseJourneyOption(const QVariantMap &object, const QStrin resultItem->setDepartureDateTime(QDateTime::fromString(leg.value("departureTime").toString(), "yyyy-MM-ddTHH:mm:ss")); resultItem->setArrivalDateTime(QDateTime::fromString(leg.value("arrivalTime").toString(), "yyyy-MM-ddTHH:mm:ss")); - resultItem->setDepartureStation(firstStop.value("commonName").toString().replace("Underground Station", "πŸš‡")); - resultItem->setArrivalStation(lastStop.value("commonName").toString().replace("Underground Station", "πŸš‡")); + resultItem->setDepartureStation( shortStationName(firstStop.value("commonName").toString())); + resultItem->setArrivalStation( shortStationName( lastStop.value("commonName").toString())); QString mode = leg.value("mode").toMap().value("name").toString(); - //const QString service = leg.value("service").toString(); - //if (!service.isEmpty()) - // typeName.append(" ").append(service); - if (mode != "walking") { // stop letter / platform (departure) @@ -769,19 +757,26 @@ void ParserLondonTfl::addTimeTableEntriesOfStopPoint(const QString & stopPointId for (i = arrivals.constBegin(); i != arrivals.constEnd(); ++i) { QVariantMap arrival = i->toMap(); + QString modeName = arrival.value("modeName").toString(); // if the mode is not correct, we skip the value - if (! doesModeMatchTrainRestrictions(arrival.value("modeName").toString(), timetableRestrictions) ) + if (! doesModeMatchTrainRestrictions(modeName, timetableRestrictions) ) { continue; } TimetableEntry entry; - entry.currentStation = arrival.value("stationName").toString(); - entry.destinationStation = arrival.value("destinationName").toString(); + entry.currentStation = shortStationName (arrival.value("stationName").toString()); + entry.destinationStation = shortStationName (arrival.value("destinationName").toString()); entry.time = QDateTime::fromString(arrival.value("expectedArrival").toString(), "yyyy-MM-ddTHH:mm:ssZ").time(); entry.platform = arrival.value("platformName").toString(); + + // for buses use the bus stop symbol + if (modeName == "bus") + { + entry.platform = "🚏" + entry.platform; + } entry.trainType = shortLineName(arrival.value("lineName").toString()); entriesList.append(entry); } From fa50aee4ba013b95252ef9d738b712fad3aa6d5a Mon Sep 17 00:00:00 2001 From: Chris Clime Date: Wed, 7 Feb 2018 20:03:28 +0100 Subject: [PATCH 67/85] if platform name is null (e.g. bus stop without letter) omit it --- src/parser/parser_london_tfl.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/parser/parser_london_tfl.cpp b/src/parser/parser_london_tfl.cpp index 552dd758..4d2c5ff8 100644 --- a/src/parser/parser_london_tfl.cpp +++ b/src/parser/parser_london_tfl.cpp @@ -770,13 +770,18 @@ void ParserLondonTfl::addTimeTableEntriesOfStopPoint(const QString & stopPointId entry.currentStation = shortStationName (arrival.value("stationName").toString()); entry.destinationStation = shortStationName (arrival.value("destinationName").toString()); entry.time = QDateTime::fromString(arrival.value("expectedArrival").toString(), "yyyy-MM-ddTHH:mm:ssZ").time(); - entry.platform = arrival.value("platformName").toString(); - // for buses use the bus stop symbol - if (modeName == "bus") + if (arrival.value("platformName").toString() != "null") { - entry.platform = "🚏" + entry.platform; + entry.platform = arrival.value("platformName").toString(); + + // for buses use the bus stop symbol + if (modeName == "bus") + { + entry.platform = "🚏" + entry.platform; + } } + entry.trainType = shortLineName(arrival.value("lineName").toString()); entriesList.append(entry); } From a6f10893ec38179b1483f56a4f0508247cfbbbd1 Mon Sep 17 00:00:00 2001 From: Chris Clime Date: Mon, 12 Feb 2018 19:46:14 +0100 Subject: [PATCH 68/85] improve platform display of arrivals --- src/parser/parser_london_tfl.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/parser/parser_london_tfl.cpp b/src/parser/parser_london_tfl.cpp index 4d2c5ff8..70172f25 100644 --- a/src/parser/parser_london_tfl.cpp +++ b/src/parser/parser_london_tfl.cpp @@ -771,15 +771,20 @@ void ParserLondonTfl::addTimeTableEntriesOfStopPoint(const QString & stopPointId entry.destinationStation = shortStationName (arrival.value("destinationName").toString()); entry.time = QDateTime::fromString(arrival.value("expectedArrival").toString(), "yyyy-MM-ddTHH:mm:ssZ").time(); - if (arrival.value("platformName").toString() != "null") + QString platformName = arrival.value("platformName").toString(); + + if ((platformName != "null") && (platformName != "Platform Unknown") ) { - entry.platform = arrival.value("platformName").toString(); + if (platformName.startsWith("Platform ")) + platformName = platformName.mid(9); // for buses use the bus stop symbol if (modeName == "bus") { - entry.platform = "🚏" + entry.platform; + platformName = "🚏" + platformName; } + + entry.platform = platformName; } entry.trainType = shortLineName(arrival.value("lineName").toString()); From ba809ab4655af2d3f952bb16c9f93c9496c7a9a7 Mon Sep 17 00:00:00 2001 From: Chris Clime Date: Wed, 14 Feb 2018 21:40:08 +0100 Subject: [PATCH 69/85] bump version --- fahrplan2.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fahrplan2.pro b/fahrplan2.pro index 083d1bbc..4190ae88 100644 --- a/fahrplan2.pro +++ b/fahrplan2.pro @@ -2,7 +2,7 @@ APP_NAME = Fahrplan # Define Version -VERSION = 2.0.32-2 +VERSION = 2.0.32-3 # Switch for jolla to separate harbour and openrepo version openrepos { From 7de6357f42dfe94acc08a04e67e6c7b65713a1f7 Mon Sep 17 00:00:00 2001 From: Chris Clime Date: Wed, 14 Feb 2018 22:40:55 +0100 Subject: [PATCH 70/85] make qt4 build work --- src/parser/parser_abstract.cpp | 1 + src/parser/parser_london_tfl.cpp | 20 ++++++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/parser/parser_abstract.cpp b/src/parser/parser_abstract.cpp index 1da28763..68f0b47d 100644 --- a/src/parser/parser_abstract.cpp +++ b/src/parser/parser_abstract.cpp @@ -214,6 +214,7 @@ QByteArray toJson(const QVariant& value) QByteArray ParserAbstract::serializeToJson(const QVariantMap& doc, bool indent) const { + Q_UNUSED(indent) return toJson(doc); } #endif diff --git a/src/parser/parser_london_tfl.cpp b/src/parser/parser_london_tfl.cpp index 70172f25..0971e7ed 100644 --- a/src/parser/parser_london_tfl.cpp +++ b/src/parser/parser_london_tfl.cpp @@ -180,7 +180,7 @@ void ParserLondonTfl::searchJourney(const Station &departureStation, QStringList modesList = getModesFromTrainRestrictions(trainrestrictions); - query.addQueryItem("mode", modesList.join(',')); + query.addQueryItem("mode", modesList.join(",")); relativeUri.setQuery(query); sendHttpRequest(BaseUrl.resolved(relativeUri)); @@ -545,7 +545,14 @@ void ParserLondonTfl::parseJourneyOption(const QVariantMap &object, const QStrin QStringList routeOptionsDirectionsCurrentTrain; QVariantMap routeOption = it_routeOpt->toMap(); - QString currentRouteOption = routeOption.value("name").toString().toHtmlEscaped(); + QString currentRouteOption = routeOption.value("name").toString(); + + #ifdef BUILD_FOR_QT5 + currentRouteOption = currentRouteOption.toHtmlEscaped(); + #else + currentRouteOption = Qt::escape(currentRouteOption); + #endif + routeOptionsTrains.push_back(currentRouteOption); detailedInfo += currentRouteOption + " to "; @@ -555,7 +562,13 @@ void ParserLondonTfl::parseJourneyOption(const QVariantMap &object, const QStrin for (it_directions = directions.constBegin(); it_directions != directions.constEnd(); ++it_directions) { - QString currentDestination = it_directions->toString().replace("Underground Station", "").toHtmlEscaped(); + QString currentDestination = it_directions->toString().replace("Underground Station", ""); + + #ifdef BUILD_FOR_QT5 + currentDestination = currentDestination.toHtmlEscaped(); + #else + currentDestination = Qt::escape(currentDestination); + #endif if (! routeOptionsDirections.contains(currentDestination)) { @@ -568,7 +581,6 @@ void ParserLondonTfl::parseJourneyOption(const QVariantMap &object, const QStrin detailedInfo += routeOptionsDirectionsCurrentTrain.join(" or ") + ".
"; } - //resultItem->setTrain(routeOptionsTrains.join(",")); resultItem->setDirection(routeOptionsDirections.join(" or ")); // walking From 60effd4dd83412bc77ffb9dd7b73e7d3488234a8 Mon Sep 17 00:00:00 2001 From: Chris Clime Date: Tue, 20 Feb 2018 18:08:25 +0100 Subject: [PATCH 71/85] add color support for TFL parser / Ubuntu touch --- src/gui/ubuntu/JourneyDetailsResultsPage.qml | 41 ++++++++++++++++---- src/parser/parser_definitions.cpp | 11 ++++++ src/parser/parser_definitions.h | 5 +++ src/parser/parser_london_tfl.cpp | 41 ++++++++++++++++++++ 4 files changed, 90 insertions(+), 8 deletions(-) diff --git a/src/gui/ubuntu/JourneyDetailsResultsPage.qml b/src/gui/ubuntu/JourneyDetailsResultsPage.qml index 88850da7..a5cf0fc2 100644 --- a/src/gui/ubuntu/JourneyDetailsResultsPage.qml +++ b/src/gui/ubuntu/JourneyDetailsResultsPage.qml @@ -111,6 +111,9 @@ Page { id: delegateItem width: listView.width height: isStation ? isTrain ? item_train.height + item_station.height : item_station.height : isTrain ? item_train.height : 0 + property string previousRouteColor: (previousTrainColor != "") ? previousTrainColor : "#0d70c5"; + property string routeColor: (trainColor != "") ? trainColor : "#0d70c5"; + Item { anchors.verticalCenter: parent.verticalCenter @@ -132,14 +135,30 @@ Page { } Rectangle { + id: arrivalLine + visible: ! isStart + anchors { + left: parent.left + leftMargin: units.gu(7.75) + top: parent.top + topMargin: 0 + } + color: previousRouteColor + height: parent.height / 2 + width: units.gu(0.5) + } + + Rectangle { + id: departureLine + visible: ! isStop anchors { left: parent.left leftMargin: units.gu(7.75) top: parent.top - topMargin: (isStart) ? parent.height / 2 : 0 + topMargin: parent.height / 2 } - color: "#0d70c5" - height: (isStart || isStop) ? parent.height / 2 : parent.height + color: routeColor + height: parent.height / 2 width: units.gu(0.5) } @@ -153,11 +172,11 @@ Page { gradient: Gradient { GradientStop { position: 0.00; - color: "#0d70c5"; + color: previousRouteColor; } GradientStop { position: 0.38; - color: "#0d70c5"; + color: previousRouteColor; } GradientStop { position: 0.39; @@ -173,11 +192,11 @@ Page { } GradientStop { position: 0.62; - color: "#0d70c5"; + color: routeColor; } GradientStop { position: 1.0; - color: "#0d70c5"; + color: routeColor; } } radius: units.gu(1) @@ -260,7 +279,7 @@ Page { left: parent.left leftMargin: units.gu(7.75) } - color: "#0d70c5" + color: routeColor height: parent.height width: units.gu(0.5) } @@ -365,6 +384,8 @@ Page { "trainName" : item.train, "trainDirection" : item.direction, "trainInfo" : item.info, + "previousTrainColor" : item.color, + "trainColor" : item.color, "stationName" : item.departureStation, "stationInfo" : item.departureInfo, "arrivalTime" : "", @@ -383,6 +404,8 @@ Page { "trainName" : "", "trainDirection": "", "trainInfo" : "", + "previousTrainColor" : item.color, + "trainColor" : item.color, "stationName" : item.arrivalStation, "stationInfo" : item.arrivalInfo, "arrivalTime" : Qt.formatTime(item.arrivalDateTime, "hh:mm"), @@ -413,6 +436,8 @@ Page { "trainName" : nextItem.train, "trainDirection" : nextItem.direction, "trainInfo" : nextItem.info, + "previousTrainColor" : item.color, + "trainColor" : nextItem.color, "stationName" : stationName, "stationInfo" : stationInfo, "arrivalTime" : Qt.formatTime(item.arrivalDateTime, "hh:mm"), diff --git a/src/parser/parser_definitions.cpp b/src/parser/parser_definitions.cpp index 13363e72..753cf7e1 100644 --- a/src/parser/parser_definitions.cpp +++ b/src/parser/parser_definitions.cpp @@ -417,6 +417,17 @@ void JourneyDetailResultItem::setDirection(const QString &direction) m_direction = direction; } + +QString JourneyDetailResultItem::color() const +{ + return m_color.isValid() ? m_color.name() : ""; +} + +void JourneyDetailResultItem::setColor(const QColor &color) +{ + m_color = color; +} + QString JourneyDetailResultItem::internalData1() const { return m_internalData1; diff --git a/src/parser/parser_definitions.h b/src/parser/parser_definitions.h index 7587c1ab..a7f72bda 100644 --- a/src/parser/parser_definitions.h +++ b/src/parser/parser_definitions.h @@ -21,6 +21,7 @@ #define PARSER_DEFINITIONS_H #include +#include #include #include #include @@ -171,6 +172,7 @@ class JourneyDetailResultItem : public QObject Q_PROPERTY(QString info READ info WRITE setInfo) Q_PROPERTY(QString train READ train WRITE setTrain) Q_PROPERTY(QString direction READ direction WRITE setDirection) + Q_PROPERTY(QString color READ color) //Some Internal Data fields, primarly to store additional data per backend, like the details url Q_PROPERTY(QString internalData1 READ internalData1 WRITE setInternalData1) @@ -194,6 +196,8 @@ class JourneyDetailResultItem : public QObject void setTrain(const QString &); QString direction() const; void setDirection(const QString &); + QString color() const; + void setColor(const QColor &); QString internalData1() const; void setInternalData1(const QString &); QString internalData2() const; @@ -208,6 +212,7 @@ class JourneyDetailResultItem : public QObject QString m_info; QString m_train; QString m_direction; + QColor m_color; QString m_internalData1; QString m_internalData2; }; diff --git a/src/parser/parser_london_tfl.cpp b/src/parser/parser_london_tfl.cpp index 0971e7ed..f1f68f77 100644 --- a/src/parser/parser_london_tfl.cpp +++ b/src/parser/parser_london_tfl.cpp @@ -76,6 +76,44 @@ namespace return outputStationName.replace("Underground Station", "πŸš‡"); } + + QColor getLineColor(const QString & mode, const QString & train = "") + { + if ((mode == "tube") && (train != "")) + { + QMap tubeColorMap; + + tubeColorMap["Bakerloo"] = QColor("#B36305"); + tubeColorMap["Central"] = QColor("#E32017"); + tubeColorMap["Circle"] = QColor("#FFD300"); + tubeColorMap["District"] = QColor("#00782A"); + tubeColorMap["Hammersmith and City"] = QColor("#F3A9BB"); + tubeColorMap["Jubilee"] = QColor("#A0A5A9"); + tubeColorMap["Metropolitan"] = QColor("#9B0056"); + tubeColorMap["Northern"] = QColor("#000000"); + tubeColorMap["Piccadilly"] = QColor("#003688"); + tubeColorMap["Victoria"] = QColor("#0098D4"); + tubeColorMap["Waterloo and City "] = QColor("#95CDBA"); + + if (tubeColorMap.find(train) == tubeColorMap.end()) + return QColor(); + + return tubeColorMap[train]; + } + + QMap modeColorMap; + + modeColorMap["bus"] = QColor("#ff0000"); + modeColorMap["dlr"] = QColor( "#00A4A7"); + modeColorMap["overground"] = QColor("#EE7C0E"); + modeColorMap["tram"] = QColor( "#84B817"); + + if (modeColorMap.find(mode) == modeColorMap.end()) + return QColor(); + + return modeColorMap[mode]; + + } } ParserLondonTfl::ParserLondonTfl(QObject *parent):ParserAbstract(parent) @@ -588,16 +626,19 @@ void ParserLondonTfl::parseJourneyOption(const QVariantMap &object, const QStrin { const QString duration = leg.value("duration").toString(); resultItem->setTrain(tr("Walk for %2 min").arg(duration)); + resultItem->setColor("#BABABA"); } // only one train --> put it in title else if (routeOptionsTrains.count() == 1) { resultItem->setTrain(routeOptionsTrains[0]); + resultItem->setColor( getLineColor(mode, routeOptionsTrains[0]) ); } else { resultItem->setTrain(mode); + resultItem->setColor(getLineColor(mode)); resultItem->setInfo(detailedInfo); } From e19cff3b4dce70f045b03d1322feea37edb04de1 Mon Sep 17 00:00:00 2001 From: Chris Clime Date: Wed, 21 Feb 2018 19:43:46 +0100 Subject: [PATCH 72/85] make color maps static add namespace TransportModes --- src/parser/parser_london_tfl.cpp | 167 +++++++++++++++++-------------- 1 file changed, 94 insertions(+), 73 deletions(-) diff --git a/src/parser/parser_london_tfl.cpp b/src/parser/parser_london_tfl.cpp index f1f68f77..d04c8aec 100644 --- a/src/parser/parser_london_tfl.cpp +++ b/src/parser/parser_london_tfl.cpp @@ -30,23 +30,27 @@ #endif #include +namespace TransportModes +{ + const QString Bus = "bus"; + const QString CableCar = "cable-car"; + const QString Coach = "coach"; + const QString Dlr = "dlr"; + const QString Rail = "national-rail"; + const QString Overground = "overground"; + const QString ReplacementBus = "replacement-bus"; + const QString RiverBus = "river-bus"; + const QString RiverTour = "river-tour"; + const QString TflRail = "tflrail"; + const QString Tram = "tram"; + const QString Tube = "tube"; + const QString Walking = "walking"; +} + namespace { const QUrl BaseUrl("https://api.tfl.gov.uk"); - const QString ModeBus = "bus"; - const QString ModeCableCar = "cable-car"; - const QString ModeCoach = "coach"; - const QString ModeDlr = "dlr"; - const QString ModeRail = "national-rail"; - const QString ModeOverground = "overground"; - const QString ModeReplacementBus = "replacement-bus"; - const QString ModeRiverBus = "river-bus"; - const QString ModeRiverTour = "river-tour"; - const QString ModeTflRail = "tflrail"; - const QString ModeTram = "tram"; - const QString ModeTube = "tube"; - bool sortByTimeLessThan(const TimetableEntry &first, const TimetableEntry &second) { if (first.time == second.time) @@ -54,7 +58,7 @@ namespace else return first.time < second.time; } - + QString shortLineName(const QString & lineName) { QMap shortNamesMap; @@ -76,43 +80,60 @@ namespace return outputStationName.replace("Underground Station", "πŸš‡"); } + + // tube color map + QMap initializeStaticTubeColorMap() { + + QMap tubeColorMap; + + tubeColorMap["Bakerloo"] = QColor("#B36305"); + tubeColorMap["Central"] = QColor("#E32017"); + tubeColorMap["Circle"] = QColor("#FFD300"); + tubeColorMap["District"] = QColor("#00782A"); + tubeColorMap["Hammersmith & City"] = QColor("#F3A9BB"); + tubeColorMap["Jubilee"] = QColor("#A0A5A9"); + tubeColorMap["Metropolitan"] = QColor("#9B0056"); + tubeColorMap["Northern"] = QColor("#000000"); + tubeColorMap["Piccadilly"] = QColor("#003688"); + tubeColorMap["Victoria"] = QColor("#0098D4"); + tubeColorMap["Waterloo & City"] = QColor("#95CDBA"); + + return tubeColorMap; + } + + const QMap tubeColorMap = initializeStaticTubeColorMap(); + + // mode color map + QMap initializeStaticModeColorMap() { + + QMap modeColorMap; + + modeColorMap[TransportModes::Bus] = QColor("#ff0000"); + modeColorMap[TransportModes::Dlr] = QColor( "#00A4A7"); + modeColorMap[TransportModes::Overground] = QColor("#EE7C0E"); + modeColorMap[TransportModes::Tram] = QColor("#84B817"); + modeColorMap[TransportModes::CableCar] = QColor("#de768b"); + modeColorMap[TransportModes::Walking] = QColor("#CBCBCB"); + + return modeColorMap; + } + + const QMap modeColorMap = initializeStaticModeColorMap(); QColor getLineColor(const QString & mode, const QString & train = "") { - if ((mode == "tube") && (train != "")) + if ((mode == TransportModes::Tube) && (train != "")) { - QMap tubeColorMap; - - tubeColorMap["Bakerloo"] = QColor("#B36305"); - tubeColorMap["Central"] = QColor("#E32017"); - tubeColorMap["Circle"] = QColor("#FFD300"); - tubeColorMap["District"] = QColor("#00782A"); - tubeColorMap["Hammersmith and City"] = QColor("#F3A9BB"); - tubeColorMap["Jubilee"] = QColor("#A0A5A9"); - tubeColorMap["Metropolitan"] = QColor("#9B0056"); - tubeColorMap["Northern"] = QColor("#000000"); - tubeColorMap["Piccadilly"] = QColor("#003688"); - tubeColorMap["Victoria"] = QColor("#0098D4"); - tubeColorMap["Waterloo and City "] = QColor("#95CDBA"); - if (tubeColorMap.find(train) == tubeColorMap.end()) return QColor(); return tubeColorMap[train]; } - QMap modeColorMap; - - modeColorMap["bus"] = QColor("#ff0000"); - modeColorMap["dlr"] = QColor( "#00A4A7"); - modeColorMap["overground"] = QColor("#EE7C0E"); - modeColorMap["tram"] = QColor( "#84B817"); - if (modeColorMap.find(mode) == modeColorMap.end()) return QColor(); return modeColorMap[mode]; - } } @@ -472,7 +493,7 @@ void ParserLondonTfl::parseSearchJourney(QNetworkReply *networkReply) for (j = legs.constBegin(); j != legs.constEnd(); ++j) { const QVariantMap mode = j->toMap().value("mode").toMap(); - if (mode.value("type").toString() != "walking") { + if (mode.value("type").toString() != TransportModes::Walking) { const QString typeName = mode.value("name").toString(); if (!typeName.isEmpty()) trains.append(typeName); @@ -550,7 +571,7 @@ void ParserLondonTfl::parseJourneyOption(const QVariantMap &object, const QStrin QString mode = leg.value("mode").toMap().value("name").toString(); - if (mode != "walking") { + if (mode != TransportModes::Walking) { // stop letter / platform (departure) if (! firstStop.value("stopLetter").toString().isEmpty()) { @@ -622,11 +643,11 @@ void ParserLondonTfl::parseJourneyOption(const QVariantMap &object, const QStrin resultItem->setDirection(routeOptionsDirections.join(" or ")); // walking - if (mode == "walking") + if (mode == TransportModes::Walking) { const QString duration = leg.value("duration").toString(); resultItem->setTrain(tr("Walk for %2 min").arg(duration)); - resultItem->setColor("#BABABA"); + resultItem->setColor(getLineColor(mode)); } // only one train --> put it in title @@ -667,55 +688,55 @@ QStringList ParserLondonTfl::getModesFromTrainRestrictions(int trainRestrictions switch(trainRestrictions){ case all: - availableModes.append(ModeBus); - availableModes.append(ModeCableCar); - availableModes.append(ModeCoach); - availableModes.append(ModeDlr); - availableModes.append(ModeRail); - availableModes.append(ModeOverground); - availableModes.append(ModeReplacementBus); - availableModes.append(ModeRiverBus); - availableModes.append(ModeRiverTour); - availableModes.append(ModeTflRail); - availableModes.append(ModeTram); - availableModes.append(ModeTube); + availableModes.append(TransportModes::Bus); + availableModes.append(TransportModes::CableCar); + availableModes.append(TransportModes::Coach); + availableModes.append(TransportModes::Dlr); + availableModes.append(TransportModes::Rail); + availableModes.append(TransportModes::Overground); + availableModes.append(TransportModes::ReplacementBus); + availableModes.append(TransportModes::RiverBus); + availableModes.append(TransportModes::RiverTour); + availableModes.append(TransportModes::TflRail); + availableModes.append(TransportModes::Tram); + availableModes.append(TransportModes::Tube); break; case bus_tram_tube_overground_dlr: - availableModes.append(ModeBus); - availableModes.append(ModeTram); - availableModes.append(ModeTube); - availableModes.append(ModeOverground); - availableModes.append(ModeDlr); + availableModes.append(TransportModes::Bus); + availableModes.append(TransportModes::Tram); + availableModes.append(TransportModes::Tube); + availableModes.append(TransportModes::Overground); + availableModes.append(TransportModes::Dlr); break; case rail_tube_overground_dlr: - availableModes.append(ModeRail); - availableModes.append(ModeTube); - availableModes.append(ModeOverground); - availableModes.append(ModeDlr); + availableModes.append(TransportModes::Rail); + availableModes.append(TransportModes::Tube); + availableModes.append(TransportModes::Overground); + availableModes.append(TransportModes::Dlr); break; case tube_overground_dlr: - availableModes.append(ModeTube); - availableModes.append(ModeOverground); - availableModes.append(ModeDlr); + availableModes.append(TransportModes::Tube); + availableModes.append(TransportModes::Overground); + availableModes.append(TransportModes::Dlr); break; case bus_tram: - availableModes.append(ModeBus); - availableModes.append(ModeTram); + availableModes.append(TransportModes::Bus); + availableModes.append(TransportModes::Tram); break; case bus: - availableModes.append(ModeBus); + availableModes.append(TransportModes::Bus); break; case rail: - availableModes.append(ModeRail); + availableModes.append(TransportModes::Rail); break; case tube: - availableModes.append(ModeTube); + availableModes.append(TransportModes::Tube); break; case overground: - availableModes.append(ModeOverground); + availableModes.append(TransportModes::Overground); break; case dlr: - availableModes.append(ModeDlr); + availableModes.append(TransportModes::Dlr); break; } @@ -832,7 +853,7 @@ void ParserLondonTfl::addTimeTableEntriesOfStopPoint(const QString & stopPointId platformName = platformName.mid(9); // for buses use the bus stop symbol - if (modeName == "bus") + if (modeName == TransportModes::Bus) { platformName = "🚏" + platformName; } From 0912bbbe9b024c6dead7fa7cb1ccb672c13db136 Mon Sep 17 00:00:00 2001 From: Chris Clime Date: Wed, 28 Feb 2018 22:33:48 +0100 Subject: [PATCH 73/85] add colors for river-boat/river-tour --- fahrplan2.pro | 2 +- src/parser/parser_london_tfl.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/fahrplan2.pro b/fahrplan2.pro index 4190ae88..902ef954 100644 --- a/fahrplan2.pro +++ b/fahrplan2.pro @@ -2,7 +2,7 @@ APP_NAME = Fahrplan # Define Version -VERSION = 2.0.32-3 +VERSION = 2.0.33 # Switch for jolla to separate harbour and openrepo version openrepos { diff --git a/src/parser/parser_london_tfl.cpp b/src/parser/parser_london_tfl.cpp index d04c8aec..e99a13ab 100644 --- a/src/parser/parser_london_tfl.cpp +++ b/src/parser/parser_london_tfl.cpp @@ -113,6 +113,8 @@ namespace modeColorMap[TransportModes::Overground] = QColor("#EE7C0E"); modeColorMap[TransportModes::Tram] = QColor("#84B817"); modeColorMap[TransportModes::CableCar] = QColor("#de768b"); + modeColorMap[TransportModes::RiverBus] = QColor("#1c3e95"); + modeColorMap[TransportModes::RiverTour] = QColor("#009ddc"); modeColorMap[TransportModes::Walking] = QColor("#CBCBCB"); return modeColorMap; From 3dc182f4979022a247e83c1b425c8e9c2e121267 Mon Sep 17 00:00:00 2001 From: Chris Clime Date: Fri, 30 Mar 2018 19:07:10 +0200 Subject: [PATCH 74/85] match open store version --- fahrplan2.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fahrplan2.pro b/fahrplan2.pro index 902ef954..4deeb7d2 100644 --- a/fahrplan2.pro +++ b/fahrplan2.pro @@ -2,7 +2,7 @@ APP_NAME = Fahrplan # Define Version -VERSION = 2.0.33 +VERSION = 2.0.33-1 # Switch for jolla to separate harbour and openrepo version openrepos { From f0f2c6c3153a9748ef9c44456e34d4d03e987d37 Mon Sep 17 00:00:00 2001 From: Chris Clime Date: Wed, 9 May 2018 13:44:02 +0200 Subject: [PATCH 75/85] change qml page headers for ubuntu (Ubuntu.Components 1.3 warnings removed) make it work with 'clickable --desktop' by changing the build folders --- clickable.json | 5 +++-- clickableCustomBuild.sh | 9 +-------- src/gui/ubuntu/MainPage.qml | 3 +-- src/gui/ubuntu/components/StationSelect.qml | 8 ++++++-- 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/clickable.json b/clickable.json index 04b7ead4..92cc1388 100644 --- a/clickable.json +++ b/clickable.json @@ -8,7 +8,8 @@ "clean_tmp": "rm -rf ./tmp/*" }, "template": "custom", - "build": "bash -c 'cd ..; ./clickableCustomBuild.sh click_build'", + "build": "bash -c 'cd ..; ./clickableCustomBuild.sh click_build/tmp'", "dependencies": [ "libcurl4-gnutls-dev" ], - "default" : "kill clean clean_tmp build click-build install launch" + "default" : "kill clean clean_tmp build click-build install launch", + "ssh_" : "bq.fritz.box" } diff --git a/clickableCustomBuild.sh b/clickableCustomBuild.sh index f86faea2..201bd70c 100755 --- a/clickableCustomBuild.sh +++ b/clickableCustomBuild.sh @@ -13,15 +13,8 @@ if [[ -z "$clickBuildFolder" ]] exit 1 fi -# make sure we are in an armhf environment -if [[ ! -d "/usr/lib/arm-linux-gnueabihf" ]] - then - echo "this script has to be run in an armhf container (e.g. docker, chroot or libertine)" - exit 1 -fi - # determine qmake (e.g. cross compiler or direct) -if [[ -n $(which qt5-qmake-arm-linux-gnueabihf) ]] +if [[ -n $(which qt5-qmake-arm-linux-gnueabihf) && -d "/usr/lib/arm-linux-gnueabihf" ]] then QMAKE=qt5-qmake-arm-linux-gnueabihf else diff --git a/src/gui/ubuntu/MainPage.qml b/src/gui/ubuntu/MainPage.qml index 5ad719f3..372afcf9 100644 --- a/src/gui/ubuntu/MainPage.qml +++ b/src/gui/ubuntu/MainPage.qml @@ -144,7 +144,6 @@ Page { font.bold: true; textSize: Label.Large elide: Text.ElideRight - text: fahrplanBackend.parserShortName } } @@ -542,7 +541,7 @@ Page { currentParserName.text = fahrplanBackend.parserShortName; updateButtonVisibility(); - selectedBackendListView.currentIndex = fahrplanBackend.backends.getItemIndexForParserId(index); + //selectedBackendListView.currentIndex = fahrplanBackend.backends.getItemIndexForParserId(index); } } diff --git a/src/gui/ubuntu/components/StationSelect.qml b/src/gui/ubuntu/components/StationSelect.qml index 617ded81..e913d67a 100644 --- a/src/gui/ubuntu/components/StationSelect.qml +++ b/src/gui/ubuntu/components/StationSelect.qml @@ -35,7 +35,10 @@ Page { property bool showFavorites: true - head.actions: [ + header: PageHeader { + + title: stationSelect.title + trailingActionBar.actions: [ Action { iconName: stationSelect.showFavorites ? "starred" : "non-starred" onTriggered: { @@ -52,11 +55,12 @@ Page { } } ] + } TextField { id: search - anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(2) } + anchors { left: parent.left; right: parent.right; top: header.bottom; margins: units.gu(2) } inputMethodHints: Qt.ImhNoPredictiveText onTextChanged: searchTimer.restart(); From 7c79f82797eb83a2f490c8d449a98f9c69ab181c Mon Sep 17 00:00:00 2001 From: Chris Clime Date: Sun, 13 May 2018 20:11:27 +0200 Subject: [PATCH 76/85] time format adjustments --- .gitignore | 1 + src/gui/desktop-test/mainwindow.cpp | 2 +- src/gui/ubuntu/JourneyDetailsResultsPage.qml | 20 ++++++++++++-------- src/gui/ubuntu/MainPage.qml | 2 +- src/gui/ubuntu/TimeTableResultsPage.qml | 2 +- src/parser/parser_hafasbinary.cpp | 12 ++++-------- src/parser/parser_xmlvasttrafikse.cpp | 4 ++-- 7 files changed, 22 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index faca3dbb..6e5a0c8c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .directory +/.qmake.* /.clickable/ /.make.cache /Makefile diff --git a/src/gui/desktop-test/mainwindow.cpp b/src/gui/desktop-test/mainwindow.cpp index f460dca3..b3c02c94 100644 --- a/src/gui/desktop-test/mainwindow.cpp +++ b/src/gui/desktop-test/mainwindow.cpp @@ -146,7 +146,7 @@ void MainWindow::timeTableResult() for (int i=0; i < fahrplan->timetable()->count(); i++) { QModelIndex index = fahrplan->timetable()->index(i, 0, QModelIndex()); ui->searchJourneyResults->append(fahrplan->timetable()->data(index, Timetable::CurrentStation).toString()); - ui->searchJourneyResults->append(fahrplan->timetable()->data(index, Timetable::Time).toTime().toString(QLocale().timeFormat(QLocale::ShortFormat))); + ui->searchJourneyResults->append(fahrplan->timetable()->data(index, Timetable::Time).toTime().toString(QLocale().timeFormat("HH:mm"))); ui->searchJourneyResults->append(fahrplan->timetable()->data(index, Timetable::DestinationStation).toString()); ui->searchJourneyResults->append(fahrplan->timetable()->data(index, Timetable::TrainType).toString()); ui->searchJourneyResults->append(fahrplan->timetable()->data(index, Timetable::Platform).toString()); diff --git a/src/gui/ubuntu/JourneyDetailsResultsPage.qml b/src/gui/ubuntu/JourneyDetailsResultsPage.qml index a5cf0fc2..4bdd05eb 100644 --- a/src/gui/ubuntu/JourneyDetailsResultsPage.qml +++ b/src/gui/ubuntu/JourneyDetailsResultsPage.qml @@ -339,7 +339,7 @@ Page { console.log(result.count); if (result.count > 0) { - titleText = result.viaStation.length == 0 ? qsTr("%1 ↦ %2").arg(result.departureStation).arg(result.arrivalStation) : qsTr("%1 ↦ %3 ↦ %2").arg(result.departureStation).arg(result.arrivalStation).arg(result.viaStation); + titleText = result.viaStation.length === 0 ? qsTr("%1 ↦ %2").arg(result.departureStation).arg(result.arrivalStation) : qsTr("%1 ↦ %3 ↦ %2").arg(result.departureStation).arg(result.arrivalStation).arg(result.viaStation); var departureDate = Qt.formatDate(result.departureDateTime); var arrivalDate = Qt.formatDate(result.arrivalDateTime); @@ -347,14 +347,18 @@ Page { arrivalDate = ""; } - subTitleText = departureDate + " " + Qt.formatTime(result.departureDateTime, Qt.DefaultLocaleShortDate) + " - " + - arrivalDate + " " + Qt.formatTime(result.arrivalDateTime, Qt.DefaultLocaleShortDate); + subTitleText = departureDate + " " + Qt.formatTime(result.departureDateTime, 'HH:mm') + " - " + arrivalDate + " " + Qt.formatTime(result.arrivalDateTime, 'HH:mm'); subTitleText2 = qsTr("Dur.: %1").arg(result.duration); journeyDetailResultModel.clear(); for (var i = 0; i < result.count; i++) { var item = result.getItem(i); + + if (item === null) + { + continue; + } var nextItem = null; if (i < result.count -1) { @@ -389,7 +393,7 @@ Page { "stationName" : item.departureStation, "stationInfo" : item.departureInfo, "arrivalTime" : "", - "departureTime" : Qt.formatTime(item.departureDateTime, "hh:mm"), + "departureTime" : Qt.formatTime(item.departureDateTime, "HH:mm"), "isStation" : true, "isTrain" : true @@ -408,7 +412,7 @@ Page { "trainColor" : item.color, "stationName" : item.arrivalStation, "stationInfo" : item.arrivalInfo, - "arrivalTime" : Qt.formatTime(item.arrivalDateTime, "hh:mm"), + "arrivalTime" : Qt.formatTime(item.arrivalDateTime, "HH:mm"), "departureTime" : "", "isStation" : true, "isTrain" : false @@ -424,7 +428,7 @@ Page { if (stationInfo.length > 0 && nextItem.departureInfo) { stationInfo = stationInfo + " / "; } - if (nextItem.departureStation != item.arrivalStation) { + if (nextItem.departureStation !== item.arrivalStation) { stationName += " / " + nextItem.departureStation; } @@ -440,8 +444,8 @@ Page { "trainColor" : nextItem.color, "stationName" : stationName, "stationInfo" : stationInfo, - "arrivalTime" : Qt.formatTime(item.arrivalDateTime, "hh:mm"), - "departureTime" : Qt.formatTime(nextItem.departureDateTime, "hh:mm"), + "arrivalTime" : Qt.formatTime(item.arrivalDateTime, "HH:mm"), + "departureTime" : Qt.formatTime(nextItem.departureDateTime, "HH:mm"), "isStation" : true, "isTrain" : true diff --git a/src/gui/ubuntu/MainPage.qml b/src/gui/ubuntu/MainPage.qml index 372afcf9..3c89ff6c 100644 --- a/src/gui/ubuntu/MainPage.qml +++ b/src/gui/ubuntu/MainPage.qml @@ -336,7 +336,7 @@ Page { id: timePickerButton title.text: qsTr("Time") - value: Qt.formatTime(fahrplanBackend.dateTime, Qt.DefaultLocaleShortDate) + value: Qt.formatTime(fahrplanBackend.dateTime, 'HH:mm') visible: timeModeSelector.selectedIndex !== 0 onClicked: { diff --git a/src/gui/ubuntu/TimeTableResultsPage.qml b/src/gui/ubuntu/TimeTableResultsPage.qml index c08c7f8a..557833a3 100644 --- a/src/gui/ubuntu/TimeTableResultsPage.qml +++ b/src/gui/ubuntu/TimeTableResultsPage.qml @@ -86,7 +86,7 @@ Page { Label { id: lbl_time - text: Qt.formatTime(model.time, Qt.DefaultLocaleShortDate) + text: Qt.formatTime(model.time, 'HH:mm') font.bold: true } diff --git a/src/parser/parser_hafasbinary.cpp b/src/parser/parser_hafasbinary.cpp index b66dcc47..44f32112 100644 --- a/src/parser/parser_hafasbinary.cpp +++ b/src/parser/parser_hafasbinary.cpp @@ -580,16 +580,12 @@ void ParserHafasBinary::parseSearchJourney(QNetworkReply *networkReply) if (realtimeStatus != 2) { item->setMiscInfo(""); } else { - item->setMiscInfo(QString("%1") - .arg(tr("Journey contains canceled trains!"))); + item->setMiscInfo(QString("%1").arg(tr("Journey contains canceled trains!"))); } item->setTrainType(lineNames.join(", ").trimmed()); - const QString timeFormat = QLocale().timeFormat(QLocale::ShortFormat); - item->setDepartureTime(inlineResults->getItem(0)->departureDateTime() - .time().toString(timeFormat)); - item->setArrivalTime(inlineResults - ->getItem(inlineResults->itemcount() - 1)->arrivalDateTime() - .time().toString(timeFormat)); + const QString timeFormat = "HH:mm"; + item->setDepartureTime(inlineResults->getItem(0)->departureDateTime().time().toString(timeFormat)); + item->setArrivalTime(inlineResults->getItem(inlineResults->itemcount() - 1)->arrivalDateTime().time().toString(timeFormat)); journeyResultsByArrivalMap.insert(inlineResults->getItem(inlineResults->itemcount() - 1)->arrivalDateTime(), item); } } diff --git a/src/parser/parser_xmlvasttrafikse.cpp b/src/parser/parser_xmlvasttrafikse.cpp index a98f7fca..339deb12 100644 --- a/src/parser/parser_xmlvasttrafikse.cpp +++ b/src/parser/parser_xmlvasttrafikse.cpp @@ -406,7 +406,7 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) const QDate date = QDate::fromString(getAttribute(originNode, "date"), QLatin1String("yyyy-MM-dd")); journeyResultList->setDepartureStation(getAttribute(originNode, "name")); //: DATE, TIME - journeyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(date.toString(Qt::DefaultLocaleShortDate)).arg(time.toString(Qt::DefaultLocaleShortDate))); + journeyResultList->setTimeInfo(tr("%1, %2", "DATE, TIME").arg(date.toString(Qt::DefaultLocaleShortDate)).arg(time.toString("HH:mm"))); } } if (j == legNodeList.length() - 1) { @@ -480,7 +480,7 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) journeyEnd = journeyEnd.addDays(1); jritem->setDate(journeyStart.date()); - const QString timeFormat = QLocale().timeFormat(QLocale::ShortFormat); + const QString timeFormat = "HH:mm"; jritem->setDepartureTime(journeyStart.time().toString(timeFormat)); jritem->setArrivalTime(journeyEnd.time().toString(timeFormat)); int diffTime = journeyStart.secsTo(journeyEnd); From e27e23bb4a0fb88240c89a8cdc3082c79ac018dd Mon Sep 17 00:00:00 2001 From: Chris Clime Date: Sat, 19 May 2018 12:55:49 +0200 Subject: [PATCH 77/85] correction of time format --- src/gui/desktop-test/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/desktop-test/mainwindow.cpp b/src/gui/desktop-test/mainwindow.cpp index b3c02c94..96061c34 100644 --- a/src/gui/desktop-test/mainwindow.cpp +++ b/src/gui/desktop-test/mainwindow.cpp @@ -146,7 +146,7 @@ void MainWindow::timeTableResult() for (int i=0; i < fahrplan->timetable()->count(); i++) { QModelIndex index = fahrplan->timetable()->index(i, 0, QModelIndex()); ui->searchJourneyResults->append(fahrplan->timetable()->data(index, Timetable::CurrentStation).toString()); - ui->searchJourneyResults->append(fahrplan->timetable()->data(index, Timetable::Time).toTime().toString(QLocale().timeFormat("HH:mm"))); + ui->searchJourneyResults->append(fahrplan->timetable()->data(index, Timetable::Time).toTime().toString("HH:mm")); ui->searchJourneyResults->append(fahrplan->timetable()->data(index, Timetable::DestinationStation).toString()); ui->searchJourneyResults->append(fahrplan->timetable()->data(index, Timetable::TrainType).toString()); ui->searchJourneyResults->append(fahrplan->timetable()->data(index, Timetable::Platform).toString()); From 94330149d9e44160f83850ae4a0ebb22d4874235 Mon Sep 17 00:00:00 2001 From: Chris Clime Date: Sat, 19 May 2018 15:00:37 +0200 Subject: [PATCH 78/85] corrections to parser_resrobot --- src/parser/parser_resrobot.cpp | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/src/parser/parser_resrobot.cpp b/src/parser/parser_resrobot.cpp index efddee24..ec0801b4 100644 --- a/src/parser/parser_resrobot.cpp +++ b/src/parser/parser_resrobot.cpp @@ -323,6 +323,9 @@ void ParserResRobot::searchJourney(const Station &departureStation, const Statio clearJourney(); + lastJourneySearch.dateTime = dateTime; + lastJourneySearch.from = departureStation; + lastJourneySearch.via = viaStation; lastJourneySearch.to = arrivalStation; lastJourneySearch.restrictions = trainRestrictions; lastJourneySearch.mode = mode; @@ -696,15 +699,13 @@ QList ParserResRobot::parseJourneySegments(const QVari while (!results.isEmpty()) delete results.takeFirst(); delete resultItem; - break; - } } if (distance.isEmpty()) { QStringList infoList; - if (!carrierInfo.isEmpty()) { - infoList << carrierInfo; + if (!operatorInfo.isEmpty()) { + infoList << operatorInfo; } if (!info.isEmpty()) { @@ -714,12 +715,7 @@ QList ParserResRobot::parseJourneySegments(const QVari resultItem->setInfo(infoList.join("
")); } else { resultItem->setInfo(distance + " m"); - else if (!operatorInfo.isEmpty() && !info.isEmpty()) - resultItem->setInfo(operatorInfo + "
" + info.join(", ")); - else if (!operatorInfo.isEmpty()) - resultItem->setInfo(operatorInfo); - else if (!info.isEmpty()) - resultItem->setInfo(info.join(", ")); + } resultItem->setDirection(segment.value("direction").toString()); results.append(resultItem); @@ -737,20 +733,11 @@ void ParserResRobot::getJourneyDetails(const QString &id) void ParserResRobot::parseSearchLaterJourney(QNetworkReply *networkReply) { parseSearchJourney(networkReply); - if (oldFirstOption != lastJourneySearch.firstOption) { - } else { - numberOfUnsuccessfulLaterSearches = 0; - } } void ParserResRobot::parseSearchEarlierJourney(QNetworkReply *networkReply) { parseSearchJourney(networkReply); - numberOfUnsuccessfulEarlierSearches = 0; - } - - if (oldLastOption != lastJourneySearch.lastOption) { - } } void ParserResRobot::parseJourneyDetails(QNetworkReply *networkReply) @@ -763,9 +750,13 @@ void ParserResRobot::parseJourneyDetails(QNetworkReply *networkReply) QString ParserResRobot::hafasAttribute(const QString& code) { if (hafasAttributes.contains(code)) + { return hafasAttributes[code]; + } else + { return ""; + } } QString ParserResRobot::transportMode(const QString& code, const QString& fallback) From 463ff3ec77de283a73fc30806f791f3bf2cf9907 Mon Sep 17 00:00:00 2001 From: Chris Clime Date: Sat, 19 May 2018 15:15:31 +0200 Subject: [PATCH 79/85] restore harbour file (do not take changes from PR) --- rpm/harbour-fahrplan2.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/rpm/harbour-fahrplan2.yaml b/rpm/harbour-fahrplan2.yaml index 1a0c542d..110be704 100644 --- a/rpm/harbour-fahrplan2.yaml +++ b/rpm/harbour-fahrplan2.yaml @@ -15,10 +15,8 @@ PkgConfigBR: - Qt5Quick - Qt5Qml - Qt5Core -- sailfishapp Requires: - sailfishsilica-qt5 >= 0.10.9 -- qt5-qtdeclarative-import-positioning Files: - '%defattr(644,root,root,-)' - '%attr(655,-,-) %{_bindir}' From 3d251c01bef775d037d453c96e682fc1f791c1d6 Mon Sep 17 00:00:00 2001 From: Chris Clime Date: Sat, 19 May 2018 16:17:59 +0200 Subject: [PATCH 80/85] original order --- src/parser/parser_resrobot.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/parser/parser_resrobot.cpp b/src/parser/parser_resrobot.cpp index ec0801b4..5f255beb 100644 --- a/src/parser/parser_resrobot.cpp +++ b/src/parser/parser_resrobot.cpp @@ -560,6 +560,12 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) } journeyDetails->appendItem(segment); } + + // When the distance is short, an option with only "walk" can be present + if (transportModes.count() == 0 && segments.count() == 1) + { + transportModes.append(segments.first()->train()); + } journeyDetails->setId(journeyID); journeyDetails->setDepartureStation(segments.first()->departureStation()); @@ -569,11 +575,6 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) journeyDetails->setDuration(duration); cachedResults.insert(journeyID, journeyDetails); - // When the distance is short, an option with only "walk" can be present - if (transportModes.isEmpty() && segments.count() == 1) { - transportModes.append(segments.first()->train()); - } - // Indicate in the departure/arrival times if they are another day (e.g. "14:37+1") int depDayDiff = lastJourneySearch.dateTime.date().daysTo(journeyDetails->departureDateTime().date()); QString depTime = journeyDetails->departureDateTime().toString("HH:mm"); From 69f9b9ed662fe2d11055609f5a56f3b16f499c0f Mon Sep 17 00:00:00 2001 From: Chris Clime Date: Sat, 19 May 2018 17:26:48 +0200 Subject: [PATCH 81/85] add cleanup to london parser --- src/parser/parser_london_tfl.cpp | 59 ++++++++++++++++++++++---------- src/parser/parser_london_tfl.h | 4 +++ 2 files changed, 45 insertions(+), 18 deletions(-) diff --git a/src/parser/parser_london_tfl.cpp b/src/parser/parser_london_tfl.cpp index e99a13ab..35add7aa 100644 --- a/src/parser/parser_london_tfl.cpp +++ b/src/parser/parser_london_tfl.cpp @@ -146,6 +146,25 @@ ParserLondonTfl::ParserLondonTfl(QObject *parent):ParserAbstract(parent) NetworkManagerTimeTableSubQuery = new QNetworkAccessManager(this); } +ParserLondonTfl::~ParserLondonTfl() +{ + clearJourney(); +} + +void ParserLondonTfl::clearJourney() +{ + if (lastJourneyResultList) { + delete lastJourneyResultList; + lastJourneyResultList = NULL; + } + + for (QMap::Iterator it = cachedResults.begin(); it != cachedResults.end();) { + JourneyDetailResultList *jdrl = it.value(); + it = cachedResults.erase(it); + delete jdrl; + } +} + void ParserLondonTfl::getTimeTableForStation(const Station ¤tStation, const Station &, const QDateTime &, @@ -464,8 +483,10 @@ void ParserLondonTfl::parseSearchJourney(QNetworkReply *networkReply) } QVariantList journeys = doc.value("journeys").toList(); + + clearJourney(); - JourneyResultList* result=new JourneyResultList; + lastJourneyResultList = new JourneyResultList(this); QDateTime arrival; QDateTime departure; @@ -478,12 +499,14 @@ void ParserLondonTfl::parseSearchJourney(QNetworkReply *networkReply) QVariantMap journey = i->toMap(); QString id = QString::number(counter); parseJourneyOption(journey, id); - JourneyResultItem* item = new JourneyResultItem; + JourneyResultItem* item = new JourneyResultItem(lastJourneyResultList); arrival = QDateTime::fromString(journey.value("arrivalDateTime").toString(), "yyyy-MM-ddTHH:mm:ss"); departure = QDateTime::fromString(journey.value("startDateTime").toString(), "yyyy-MM-ddTHH:mm:ss"); if (i == journeys.constBegin()) + { lastsearch.firstOption=departure; + } item->setArrivalTime(arrival.toString("HH:mm")); item->setDepartureTime(departure.toString("HH:mm")); @@ -513,17 +536,17 @@ void ParserLondonTfl::parseSearchJourney(QNetworkReply *networkReply) item->setId(id); - result->appendItem(item); + lastJourneyResultList->appendItem(item); //Set result metadata based on first result - if (result->itemcount() == 1) { - result->setTimeInfo(arrival.date().toString()); - result->setDepartureStation(cachedResults[item->id()]->departureStation()); - result->setArrivalStation(cachedResults[item->id()]->arrivalStation()); + if (lastJourneyResultList->itemcount() == 1) { + lastJourneyResultList->setTimeInfo(arrival.date().toString()); + lastJourneyResultList->setDepartureStation(cachedResults[item->id()]->departureStation()); + lastJourneyResultList->setArrivalStation(cachedResults[item->id()]->arrivalStation()); } } lastsearch.lastOption=departure; - emit journeyResult(result); + emit journeyResult(lastJourneyResultList); } void ParserLondonTfl::parseSearchLaterJourney(QNetworkReply *) @@ -543,25 +566,25 @@ void ParserLondonTfl::parseJourneyDetails(QNetworkReply *) void ParserLondonTfl::parseJourneyOption(const QVariantMap &object, const QString &id) { - JourneyDetailResultList* result = new JourneyDetailResultList; + JourneyDetailResultList* resultList = new JourneyDetailResultList(this); QVariantList legs = object.value("legs").toList(); QDateTime arrival = QDateTime::fromString(object.value("arrivalDateTime").toString(), "yyyy-MM-ddTHH:mm:ss"); QDateTime departure = QDateTime::fromString(object.value("startDateTime").toString(), "yyyy-MM-ddTHH:mm:ss"); - result->setArrivalDateTime(arrival); - result->setDepartureDateTime(departure); + resultList->setArrivalDateTime(arrival); + resultList->setDepartureDateTime(departure); int minutes=departure.secsTo(arrival)/60; int hours=minutes/60; minutes=minutes%60; - result->setDuration(QString("%1:%2").arg(hours).arg(minutes, 2, 10, QChar('0'))); + resultList->setDuration(QString("%1:%2").arg(hours).arg(minutes, 2, 10, QChar('0'))); - result->setId(id); + resultList->setId(id); for(int i = 0; i < legs.count(); i++) { QVariantMap leg = legs.at(i).toMap(); - JourneyDetailResultItem* resultItem = new JourneyDetailResultItem; + JourneyDetailResultItem* resultItem = new JourneyDetailResultItem(resultList); QVariantMap firstStop = leg["departurePoint"].toMap(); QVariantMap lastStop = leg["arrivalPoint"].toMap(); @@ -674,13 +697,13 @@ void ParserLondonTfl::parseJourneyOption(const QVariantMap &object, const QStrin } //resultItem->setInfo(attributes.join(tr(", "))); - result->appendItem(resultItem); + resultList->appendItem(resultItem); } - result->setDepartureStation(result->getItem(0)->departureStation()); - result->setArrivalStation(result->getItem(result->itemcount() - 1)->arrivalStation()); + resultList->setDepartureStation(resultList->getItem(0)->departureStation()); + resultList->setArrivalStation(resultList->getItem(resultList->itemcount() - 1)->arrivalStation()); - cachedResults.insert(id, result); + cachedResults.insert(id, resultList); } QStringList ParserLondonTfl::getModesFromTrainRestrictions(int trainRestrictions) diff --git a/src/parser/parser_london_tfl.h b/src/parser/parser_london_tfl.h index db565d1f..9850b285 100644 --- a/src/parser/parser_london_tfl.h +++ b/src/parser/parser_london_tfl.h @@ -67,6 +67,7 @@ class ParserLondonTfl : public ParserAbstract public: ParserLondonTfl(QObject* parent = 0); + virtual ~ParserLondonTfl(); // ParserAbstract interface public: @@ -87,6 +88,7 @@ public slots: bool supportsTimeTable() { return true; } bool supportsTimeTableDirection() { return false; } QStringList getTrainRestrictions(); + virtual void clearJourney(); protected: void parseTimeTable(QNetworkReply *networkReply); @@ -97,6 +99,8 @@ public slots: void parseSearchEarlierJourney(QNetworkReply *networkReply); void parseJourneyDetails(QNetworkReply *networkReply); QMap cachedResults; + + JourneyResultList *lastJourneyResultList; private: void parseJourneyOption(const QVariantMap &object, const QString & id); From 7296824f4f45507bd3196094347fc416da91a262 Mon Sep 17 00:00:00 2001 From: Chris Clime Date: Mon, 21 May 2018 22:49:32 +0200 Subject: [PATCH 82/85] ubuntu gui adaption for parsers that do not support timetable, correction to london parser --- src/gui/ubuntu/MainPage.qml | 17 ++++++++++++----- src/parser/parser_london_tfl.cpp | 2 +- src/parser/parser_xmlrmvde.h | 1 + 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/gui/ubuntu/MainPage.qml b/src/gui/ubuntu/MainPage.qml index 3c89ff6c..c3d5c596 100644 --- a/src/gui/ubuntu/MainPage.qml +++ b/src/gui/ubuntu/MainPage.qml @@ -28,24 +28,25 @@ Page { id: mainPage property int searchmode : 0 + property bool timeTableEnabled: true property bool startup : true header: PageHeader { title: tabs.selectedTabIndex === 0 ? qsTr("Journey") : qsTr("Time table") flickable: flickable - + leadingActionBar.actions: [ Action { text: qsTr("Journey") onTriggered: tabs.selectedTabIndex = 0 }, - Action { text: qsTr("Time table") onTriggered: tabs.selectedTabIndex = 1 + enabled: timeTableEnabled } ] - + leadingActionBar.numberOfSlots: 0 trailingActionBar.actions: Action { @@ -67,8 +68,14 @@ Page { function updateButtonVisibility() { - if (!fahrplanBackend.parser.supportsTimeTable()) { - searchmode = 0; + //console.log("button..."); + + if (fahrplanBackend.parser.supportsTimeTable()) { + timeTableEnabled = true; + } + else { + timeTableEnabled = false; + tabs.selectedTabIndex = 0 } if (searchmode == 0) { diff --git a/src/parser/parser_london_tfl.cpp b/src/parser/parser_london_tfl.cpp index 35add7aa..d8141103 100644 --- a/src/parser/parser_london_tfl.cpp +++ b/src/parser/parser_london_tfl.cpp @@ -139,7 +139,7 @@ namespace } } -ParserLondonTfl::ParserLondonTfl(QObject *parent):ParserAbstract(parent) +ParserLondonTfl::ParserLondonTfl(QObject *parent):ParserAbstract(parent),lastJourneyResultList(NULL) { lastCoordinates.isValid = false; diff --git a/src/parser/parser_xmlrmvde.h b/src/parser/parser_xmlrmvde.h index 38bd663a..2641068a 100644 --- a/src/parser/parser_xmlrmvde.h +++ b/src/parser/parser_xmlrmvde.h @@ -31,6 +31,7 @@ class ParserXmlRMVde : public ParserHafasXml static QString getName() { return QString(QLatin1String("%1 (rmv.de)")).arg(tr("Germany, Hesse")); } virtual QString name() { return getName(); } virtual QString shortName() { return QLatin1String("rmv.de"); } + bool supportsTimeTable() { return false; } protected: void parseStationsByName(QNetworkReply *networkReply); From 2aef7c6cd02284c9fc099231ba559cb503d78a71 Mon Sep 17 00:00:00 2001 From: Chris Clime Date: Sun, 3 Jun 2018 10:53:44 +0200 Subject: [PATCH 83/85] minor change london parser --- .gitignore | 1 + src/parser/parser_london_tfl.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 6e5a0c8c..cfada9b9 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ /run_on_ubuntu_touch.sh /tmp/ /translations/*.qm +/rpm/harbour-fahrplan2.spec diff --git a/src/parser/parser_london_tfl.cpp b/src/parser/parser_london_tfl.cpp index d8141103..6eeb1cdd 100644 --- a/src/parser/parser_london_tfl.cpp +++ b/src/parser/parser_london_tfl.cpp @@ -243,7 +243,8 @@ void ParserLondonTfl::searchJourney(const Station &departureStation, lastsearch.restrictions=trainrestrictions; lastsearch.via=viaStation; - QUrl relativeUri(QString("Journey/Journeyresults/%1/to/%2").arg(parseJson(departureStation.id.toByteArray()).value("icsId").toString(), parseJson(arrivalStation.id.toByteArray()).value("icsId").toString())); + QUrl relativeUri(QString("/Journey/Journeyresults/%1/to/%2").arg(parseJson(departureStation.id.toByteArray()).value("icsId").toString(), + parseJson(arrivalStation.id.toByteArray()).value("icsId").toString())); #if defined(BUILD_FOR_QT5) QUrlQuery query; From aaa15897543958c8e8f4c8a63772d6e57c2efa24 Mon Sep 17 00:00:00 2001 From: Chris Clime Date: Sun, 3 Jun 2018 10:59:37 +0200 Subject: [PATCH 84/85] raise version --- fahrplan2.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fahrplan2.pro b/fahrplan2.pro index afce2dad..adc07eed 100644 --- a/fahrplan2.pro +++ b/fahrplan2.pro @@ -2,7 +2,7 @@ APP_NAME = Fahrplan # Define Version -VERSION = 2.0.33-1 +VERSION = 2.0.33-2 # Switch for jolla to separate harbour and openrepo version openrepos { From e35efbe37abdb4539464f4771f32319d9b233d31 Mon Sep 17 00:00:00 2001 From: ennedin <36576290+ennedin@users.noreply.github.com> Date: Thu, 13 Sep 2018 12:49:28 +0200 Subject: [PATCH 85/85] Change layout height to make full text visible on the About page's Credits tab (Ubuntu Touch) --- src/gui/ubuntu/AboutPage.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/ubuntu/AboutPage.qml b/src/gui/ubuntu/AboutPage.qml index 361d820d..60f9578a 100644 --- a/src/gui/ubuntu/AboutPage.qml +++ b/src/gui/ubuntu/AboutPage.qml @@ -146,7 +146,7 @@ Page { Item { width: tabView.width - height: tabView.height + height: tabView.height - header.height Flickable { clip: true @@ -154,7 +154,7 @@ Page { flickableDirection: Flickable.VerticalFlick contentWidth: width - contentHeight: creditsColumn.height + units.gu(2) + contentHeight: creditsColumn.height + units.gu(4) Column { id: creditsColumn