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/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; 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.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 8072f1ee..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(); @@ -89,7 +91,7 @@ public slots: void run(); private: - bool m_ready; + volatile bool m_ready; int i_parser; QStringList m_trainrestrictions; diff --git a/src/parser/parser_abstract.cpp b/src/parser/parser_abstract.cpp index 86ade9e1..13d47901 100644 --- a/src/parser/parser_abstract.cpp +++ b/src/parser/parser_abstract.cpp @@ -36,14 +36,14 @@ #endif ParserAbstract::ParserAbstract(QObject *parent) : - QObject(parent) + QObject(parent), lastRequest(NULL) { NetworkManager = new QNetworkAccessManager(this); connect(NetworkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkReplyFinished(QNetworkReply*))); 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); diff --git a/src/parser/parser_definitions.cpp b/src/parser/parser_definitions.cpp index 13363e72..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(); @@ -127,6 +137,10 @@ void JourneyResultList::setTimeInfo(const QString &timeInfo) } //------------- JourneyResultItem +JourneyResultItem::JourneyResultItem(QObject *parent) : QObject(parent) +{ + +} QString JourneyResultItem::id() const { @@ -230,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; @@ -327,6 +351,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..e15d1620 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; @@ -140,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; @@ -176,6 +179,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; @@ -228,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; diff --git a/src/parser/parser_efa.cpp b/src/parser/parser_efa.cpp index d934be35..9ece516b 100755 --- a/src/parser/parser_efa.cpp +++ b/src/parser/parser_efa.cpp @@ -99,15 +99,35 @@ #include #endif -QHash cachedJourneyDetailsEfa; +//QHash cachedJourneyDetailsEfa; ParserEFA::ParserEFA(QObject *parent) : - ParserAbstract(parent){ + ParserAbstract(parent), lastJourneyResultList(NULL) +{ m_searchJourneyParameters.isValid = false; m_timeTableForStationParameters.isValid = false; } +ParserEFA::~ParserEFA() +{ + clearJourney(); +} + +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; + } +} + bool ParserEFA::supportsGps() { return true; @@ -402,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; @@ -504,13 +526,8 @@ void ParserEFA::searchJourney(const Station &departureStation, const Station &vi void ParserEFA::parseSearchJourney(QNetworkReply *networkReply) { qDebug() << "ParserEFA::parseSearchJourney(QNetworkReply *networkReply)"; - lastJourneyResultList = new JourneyResultList(); - for (QHash::Iterator it = cachedJourneyDetailsEfa.begin(); it != cachedJourneyDetailsEfa.end();) { - JourneyDetailResultList *jdrl = it.value(); - it = cachedJourneyDetailsEfa.erase(it); - delete jdrl; - } + lastJourneyResultList = new JourneyResultList(this); /// Use fallback values for empty results (i.e. no connections found) lastJourneyResultList->setDepartureStation(m_searchJourneyParameters.departureStation.name); @@ -528,7 +545,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"); @@ -542,7 +559,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")); @@ -578,9 +595,9 @@ 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(); + JourneyResultItem *item = new JourneyResultItem(lastJourneyResultList); item->setDate(departureDateTime.date()); item->setId(id); item->setTransfers(changes); @@ -591,10 +608,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); @@ -619,20 +639,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); } } @@ -642,13 +661,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_efa.h b/src/parser/parser_efa.h index 1ce9573b..6d95cc93 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; @@ -59,6 +61,7 @@ public slots: private: JourneyResultList *lastJourneyResultList; + QHash cachedJourneyDetailsEfa; struct { bool isValid; diff --git a/src/parser/parser_hafasbinary.cpp b/src/parser/parser_hafasbinary.cpp index b66dcc47..42da5a31 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; + + clearJourney(); 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,11 +325,11 @@ void ParserHafasBinary::parseSearchJourney(QNetworkReply *networkReply) qDebug()<<"conId"<seek(0x4a + partsOffset + iPart * 20); @@ -571,7 +572,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)); @@ -633,6 +634,8 @@ void ParserHafasBinary::searchJourneyLater() currentRequestState = FahrplanNS::searchJourneyLaterRequest; + clearJourney(); + QUrl uri = baseBinaryUrl; #if defined(BUILD_FOR_QT5) QUrlQuery query; @@ -668,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 ee129b3c..ad4e9c46 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 @@ -50,6 +50,24 @@ ParserHafasXml::ParserHafasXml(QObject *parent) : STTableMode = 0; } +ParserHafasXml::~ParserHafasXml() +{ + clearJourney(); +} + +void ParserHafasXml::clearJourney() +{ + if (lastJourneyResultList) { + delete lastJourneyResultList; + lastJourneyResultList = NULL; + } + + if (!journeyDetailInlineData.isEmpty()) { + qDeleteAll(journeyDetailInlineData); + journeyDetailInlineData.clear(); + } +} + bool ParserHafasXml::supportsGps() { return true; @@ -518,7 +536,8 @@ void ParserHafasXml::searchJourney(const Station &departureStation, const Statio currentRequestState = FahrplanNS::searchJourneyRequest; hafasContext.seqNr = ""; - lastJourneyResultList = NULL; + + clearJourney(); QString trainrestr = getTrainRestrictionsCodes(trainrestrictions); @@ -647,8 +666,7 @@ QString ParserHafasXml::parseExternalIds(const QVariant &id) const void ParserHafasXml::parseSearchJourney(QNetworkReply *networkReply) { - lastJourneyResultList = new JourneyResultList(); - journeyDetailInlineData.clear(); + lastJourneyResultList = new JourneyResultList(this); QDomDocument doc; if (!parseXml(doc, networkReply->readAll())) @@ -656,7 +674,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"); @@ -749,6 +767,8 @@ void ParserHafasXml::searchJourneyLater() currentRequestState = FahrplanNS::searchJourneyLaterRequest; + clearJourney(); + QByteArray postData = ""; postData.append(""); postData.append(""); @@ -774,6 +794,8 @@ void ParserHafasXml::searchJourneyEarlier() currentRequestState = FahrplanNS::searchJourneyEarlierRequest; + clearJourney(); + QByteArray postData = ""; postData.append(""); postData.append(""); @@ -842,11 +864,11 @@ 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) { - JourneyDetailResultItem *item = new JourneyDetailResultItem(); + JourneyDetailResultItem *item = new JourneyDetailResultItem(results); const QDomNode section = sections.at(i); QDomElement stop; diff --git a/src/parser/parser_hafasxml.h b/src/parser/parser_hafasxml.h index aee85971..513d206a 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(); } @@ -74,6 +75,7 @@ public slots: bool supportsTimeTable(); bool supportsTimeTableDirection(); QStringList getTrainRestrictions(); + virtual void clearJourney(); protected: QString baseXmlUrl; diff --git a/src/parser/parser_ninetwo.cpp b/src/parser/parser_ninetwo.cpp index 0386775d..aca8830d 100644 --- a/src/parser/parser_ninetwo.cpp +++ b/src/parser/parser_ninetwo.cpp @@ -49,11 +49,30 @@ 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; } +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 &, @@ -166,6 +185,8 @@ void ParserNinetwo::searchJourney(const Station &departureStation, currentRequestState=FahrplanNS::searchJourneyRequest; + clearJourney(); + } void ParserNinetwo::searchJourneyLater() @@ -334,9 +355,23 @@ 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(); - JourneyResultList* result=new JourneyResultList; + clearJourney(); + + lastJourneyResultList = new JourneyResultList(this); QDateTime arrival; QDateTime departure; @@ -345,13 +380,15 @@ 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(lastJourneyResultList); 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")); @@ -376,17 +413,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 +443,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(); @@ -424,7 +461,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_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); }; diff --git a/src/parser/parser_resrobot.cpp b/src/parser/parser_resrobot.cpp index c0fbc0cb..e962175d 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/")), @@ -87,6 +88,25 @@ ParserResRobot::ParserResRobot(QObject *parent) : transportModeStrings[QString::fromUtf8("Övriga tåg")] = tr("Other train"); } +ParserResRobot::~ParserResRobot() +{ + clearJourney(); +} + +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; + } +} + bool ParserResRobot::supportsGps() { return true; @@ -119,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")); @@ -145,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")); @@ -180,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 @@ -211,9 +241,14 @@ 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; + + clearJourney(); + numberOfUnsuccessfulEarlierSearches = 0; numberOfUnsuccessfulLaterSearches = 0; internalSearchJourney(departureStation, viaStation, arrivalStation, dateTime, mode, trainRestrictions); @@ -224,11 +259,14 @@ 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; + clearJourney(); internalSearchJourney(lastJourneySearch.from, lastJourneySearch.via, lastJourneySearch.to, time, lastJourneySearch.mode, lastJourneySearch.restrictions); } @@ -239,11 +277,14 @@ 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; + clearJourney(); internalSearchJourney(lastJourneySearch.from, lastJourneySearch.via, lastJourneySearch.to, time, lastJourneySearch.mode, lastJourneySearch.restrictions); } @@ -274,20 +315,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); @@ -312,8 +358,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) { @@ -334,8 +381,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(); @@ -425,12 +473,11 @@ 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(); - - JourneyResultList *journeyList = new JourneyResultList(); + lastJourneyResultList = new JourneyResultList(this); int journeyCounter = 0; foreach (QVariant journeyData, journeyListData) { @@ -444,19 +491,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; - foreach (JourneyDetailResultItem* segment, segments) - journeyDetails->appendItem(segment); journeyDetails->setId(journeyID); journeyDetails->setDepartureStation(segments.first()->departureStation()); journeyDetails->setDepartureDateTime(segments.first()->departureDateTime()); @@ -465,13 +509,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) @@ -479,7 +530,7 @@ void ParserResRobot::parseSearchJourney(QNetworkReply *networkReply) else if (arrDayDiff < 0) arrTime += QString::number(arrDayDiff); - JourneyResultItem* journey = new JourneyResultItem; + JourneyResultItem* journey = new JourneyResultItem(lastJourneyResultList); journey->setId(journeyID); journey->setDate(segments.first()->departureDateTime().date()); journey->setDepartureTime(depTime); @@ -487,31 +538,37 @@ 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) + 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; } - 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) + if (lastJourneySearch.mode == Arrival) { modeString = tr("Arrivals"); - else + } else { modeString = tr("Departures"); - journeyList->setTimeInfo(modeString + " " + lastJourneySearch.dateTime.toString(tr("ddd MMM d, HH:mm"))); + } - emit journeyResult(journeyList); + lastJourneyResultList->setTimeInfo(modeString + " " + lastJourneySearch.dateTime.toString(tr("ddd MMM d, HH:mm"))); + + emit journeyResult(lastJourneyResultList); } // Parse info about one journey option. Store detailed info about segments for later use. @@ -520,10 +577,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; + JourneyDetailResultItem* resultItem = new JourneyDetailResultItem(this); // Departure QVariantMap departure = segment.value("departure").toMap(); @@ -550,35 +606,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); @@ -588,8 +656,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) @@ -597,12 +666,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) @@ -610,12 +683,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 3ddef51a..ecbfb422 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, @@ -123,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; diff --git a/src/parser/parser_xmlvasttrafikse.cpp b/src/parser/parser_xmlvasttrafikse.cpp index 75534115..cf2190b5 100644 --- a/src/parser/parser_xmlvasttrafikse.cpp +++ b/src/parser/parser_xmlvasttrafikse.cpp @@ -40,12 +40,30 @@ 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; } +ParserXmlVasttrafikSe::~ParserXmlVasttrafikSe() +{ + clearJourney(); +} + +void ParserXmlVasttrafikSe::clearJourney() +{ + if (lastJourneyResultList) { + 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) { @@ -142,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; @@ -305,20 +325,14 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) { qDebug() << "ParserXmlVasttrafikSe::parseSearchJourney(networkReply.url()=" << networkReply->url().toString() << ")"; - JourneyResultList *journeyResultList = new JourneyResultList(); - - for (QHash::Iterator it = cachedJourneyDetails.begin(); it != cachedJourneyDetails.end();) { - JourneyDetailResultList *jdrl = it.value(); - it = cachedJourneyDetails.erase(it); - delete jdrl; - } + lastJourneyResultList = new JourneyResultList(this); /// 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 +343,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(); - 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 +365,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")) { @@ -367,7 +381,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)); @@ -441,14 +455,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 +475,7 @@ void ParserXmlVasttrafikSe::parseSearchJourney(QNetworkReply *networkReply) } } - emit journeyResult(journeyResultList); + emit journeyResult(lastJourneyResultList); } void ParserXmlVasttrafikSe::searchJourneyLater() @@ -469,13 +483,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(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); } } @@ -484,13 +499,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(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_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;