diff --git a/plugins/messageviewer/bodypartformatter/semantic/semanticmemento.cpp b/plugins/messageviewer/bodypartformatter/semantic/semanticmemento.cpp index ddbb42eb..284d23f0 100644 --- a/plugins/messageviewer/bodypartformatter/semantic/semanticmemento.cpp +++ b/plugins/messageviewer/bodypartformatter/semantic/semanticmemento.cpp @@ -1,141 +1,154 @@ /* Copyright (c) 2017 Volker Krause This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "semanticmemento.h" #include #include #include #include #include #include #include using namespace KItinerary; void SemanticMemento::detach() { } bool SemanticMemento::isParsed(const KMime::ContentIndex &index) const { return m_parsedParts.contains(index); } void SemanticMemento::setParsed(const KMime::ContentIndex &index) { m_parsedParts.insert(index); } void SemanticMemento::setMessageDate(const QDateTime &contextDt) { m_postProc.setContextDate(contextDt); } void SemanticMemento::appendStructuredData(const QVector &data) { m_pendingStructuredData.append(data); } void SemanticMemento::appendUnstructuredData(const QVector &data) { m_postProc.process(data); } bool SemanticMemento::hasData() const { return !m_data.isEmpty() || !m_pendingStructuredData.isEmpty() || !m_postProc.result().isEmpty(); } QVector SemanticMemento::data() { if (!m_pendingStructuredData.isEmpty()) { m_postProc.process(m_pendingStructuredData); m_pendingStructuredData.clear(); } if (m_data.isEmpty() && !m_postProc.result().isEmpty()) { // perform calendar lookup and merge results std::vector> resolvedEvents; resolvedEvents.reserve(m_postProc.result().size()); const auto calendar = CalendarSupport::calendarSingleton(true); for (const auto &r : m_postProc.result()) { auto e = std::make_pair(r, CalendarHandler::findEvent(calendar, r)); if (e.second) { const auto existingRes = CalendarHandler::reservationsForEvent(e.second); for (const auto &ev : existingRes) { if (MergeUtil::isSame(ev, e.first)) { e.first = JsonLdDocument::apply(ev, e.first); break; } } } resolvedEvents.push_back(e); } // merge multi-traveler elements for (auto it = resolvedEvents.begin(); it != resolvedEvents.end();) { TripData data; data.reservations.push_back((*it).first); data.event = (*it).second; data.expanded = false; ++it; if (JsonLd::canConvert(data.reservations.at(0))) { const auto trip = JsonLd::convert(data.reservations.at(0)).reservationFor(); for (; it != resolvedEvents.end(); ++it) { if (!JsonLd::canConvert((*it).first) || !MergeUtil::isSame(JsonLd::convert((*it).first).reservationFor(), trip)) { break; } data.reservations.push_back((*it).first); } + + // add other traveler we already know about from previous data in the calendar + // but that aren't in the currently extracted data set + if (data.event) { + for (const auto &prev : CalendarHandler::reservationsForEvent(data.event)) { + const auto notFound = std::find_if(data.reservations.constBegin(), data.reservations.constEnd(), [prev](const QVariant &v) { + return MergeUtil::isSame(v, prev); + }) == data.reservations.constEnd(); + if (notFound) { + data.reservations.push_back(prev); + } + } + } } m_data.push_back(data); } } return m_data; } void SemanticMemento::toggleExpanded(int index) { if (index >= m_data.size()) { return; } m_data[index].expanded = !m_data.at(index).expanded; } void SemanticMemento::addPass(KPkPass::Pass *pass, const QByteArray &rawData) { m_passes.emplace_back(PassData{pass->passTypeIdentifier(), pass->serialNumber(), rawData}); } QByteArray SemanticMemento::rawPassData(const QString &passTypeIdentifier, const QString &serialNumber) const { for (const auto &pass : m_passes) { if (pass.passTypeIdentifier == passTypeIdentifier && pass.serialNumber == serialNumber) { return pass.rawData; } } return {}; }