diff --git a/plugins/plasma/pimeventsplugin/autotests/eventdatavisitortest.cpp b/plugins/plasma/pimeventsplugin/autotests/eventdatavisitortest.cpp index 370b6742..1006de58 100644 --- a/plugins/plasma/pimeventsplugin/autotests/eventdatavisitortest.cpp +++ b/plugins/plasma/pimeventsplugin/autotests/eventdatavisitortest.cpp @@ -1,302 +1,302 @@ /* * Copyright (C) 2016 Daniel Vrátil * * 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include "eventdatavisitortest.h" #include "testdataparser.h" #include "fakepimdatasource.h" #include "testutils.h" #include "../eventdatavisitor.h" #include #include #include #include Q_DECLARE_METATYPE(CalendarEvents::EventData) Q_DECLARE_METATYPE(KCalCore::Incidence::Ptr) template class TestableVisitor : public Visitor { public: TestableVisitor(PimDataSource *source, const QDate &start = QDate(), const QDate &end = QDate()) : Visitor(source, start, end) { } QString callGenerateUid(const KCalCore::Incidence::Ptr &incidence, const QDateTime &recurrenceId) const { return Visitor::generateUid(incidence, recurrenceId); } bool callIsInRange(const QDate &start, const QDate &end) const { return Visitor::isInRange(start, end); } QVector callExplodeIncidenceOccurences(const CalendarEvents::EventData &baseEd, const KCalCore::Incidence::Ptr &incidence, bool &ok) { return Visitor::explodeIncidenceOccurences(baseEd, incidence, ok); } }; using TestableEventDataVisitor = TestableVisitor; using TestableEventDataIdVisitor = TestableVisitor; using DateTimeRange = QPair; void EventDataVisitorTest::initTestCase() { qputenv("TZ", "Europe/Berlin"); } void EventDataVisitorTest::testGenerateUID_data() { QTest::addColumn("incidence"); QTest::addColumn("recurrenceId"); QTest::addColumn("itemId"); QTest::addColumn("expectedUID"); auto incidence = KCalCore::Event::Ptr::create().staticCast(); QTest::newRow("simple event") << incidence << QDateTime() << 1ll << QStringLiteral("Akonadi-1"); QTest::newRow("recurring event") << incidence << QDateTime(QDate(2016, 5, 29), QTime(15, 47, 0), Qt::UTC) << 1ll << QStringLiteral("Akonadi-1-20160529T154700UTC"); incidence = KCalCore::Todo::Ptr::create().staticCast(); QTest::newRow("simple todo") << incidence << QDateTime() << 42ll << QStringLiteral("Akonadi-42"); QTest::newRow("recurring todo") << incidence << QDateTime(QDate(2016, 5, 29), QTime(15, 49, 5), Qt::UTC) << 42ll << QStringLiteral("Akonadi-42-20160529T154905UTC"); } void EventDataVisitorTest::testGenerateUID() { QFETCH(KCalCore::Incidence::Ptr, incidence); QFETCH(QDateTime, recurrenceId); QFETCH(qint64, itemId); QFETCH(QString, expectedUID); FakePimDataSource source; source.setAkonadiIdForIncidence(incidence, itemId); TestableEventDataVisitor visitor(&source); const QString result = visitor.callGenerateUid(incidence, recurrenceId); QCOMPARE(result, expectedUID); } void EventDataVisitorTest::testIsInRange_data() { QTest::addColumn("rangeStart"); QTest::addColumn("rangeEnd"); QTest::addColumn("eventStart"); QTest::addColumn("eventEnd"); QTest::addColumn("expectedResult"); QTest::newRow("single day fully in-range") << QDate(2016, 5, 1) << QDate(2016, 5, 31) << QDate(2016, 5, 3) << QDate(2016, 5, 3) << true; QTest::newRow("multiday fully in-range") << QDate(2016, 5, 1) << QDate(2016, 5, 31) << QDate(2016, 5, 3) << QDate(2016, 5, 15) << true; QTest::newRow("multiday start overlap") << QDate(2016, 5, 1) << QDate(2016, 5, 31) << QDate(2016, 4, 28) << QDate(2016, 5, 5) << true; QTest::newRow("multiday end overlap") << QDate(2016, 5, 1) << QDate(2016, 5, 31) << QDate(2016, 5, 28) << QDate(2016, 6, 5) << true; QTest::newRow("single day range edge start") << QDate(2016, 5, 1) << QDate(2016, 5, 31) << QDate(2016, 5, 1) << QDate(2016, 5, 1) << true; QTest::newRow("single day range edge end") << QDate(2016, 5, 1) << QDate(2016, 5, 31) << QDate(2016, 5, 31) << QDate(2016, 5, 31) << true; QTest::newRow("multiday range edge start") << QDate(2016, 5, 1) << QDate(2016, 5, 31) << QDate(2016, 5, 1) << QDate(2016, 5, 10) << true; QTest::newRow("multiday range edge end") << QDate(2016, 5, 1) << QDate(2016, 5, 31) << QDate(2016, 5, 20) << QDate(2016, 5, 31) << true; QTest::newRow("single day before range") << QDate(2016, 5, 1) << QDate(2016, 5, 31) << QDate(2016, 4, 28) << QDate(2016, 4, 28) << false; QTest::newRow("single day after range") << QDate(2016, 5, 1) << QDate(2016, 5, 31) << QDate(2016, 6, 4) << QDate(2016, 6, 4) << false; QTest::newRow("multiday before range") << QDate(2016, 5, 1) << QDate(2016, 5, 31) << QDate(2016, 4, 12) << QDate(2016, 4, 20) << false; QTest::newRow("multiday after range") << QDate(2016, 5, 1) << QDate(2016, 5, 31) << QDate(2016, 6, 5) << QDate(2016, 6, 10) << false; } void EventDataVisitorTest::testIsInRange() { QFETCH(QDate, rangeStart); QFETCH(QDate, rangeEnd); QFETCH(QDate, eventStart); QFETCH(QDate, eventEnd); QFETCH(bool, expectedResult); FakePimDataSource source; TestableEventDataVisitor visitor(&source, rangeStart, rangeEnd); const bool result = visitor.callIsInRange(eventStart, eventEnd); QCOMPARE(result, expectedResult); } void EventDataVisitorTest::testExplodeIncidenceOccurences_data() { QTest::addColumn("rangeStart"); QTest::addColumn("rangeEnd"); QTest::addColumn("baseEventData"); QTest::addColumn("incidence"); QTest::addColumn("akonadiItemId"); QTest::addColumn >("expectedEventData"); const auto allTestData = TestDataParser::allTestData(); for (const auto &testData : allTestData) { TestDataParser parser(testData, true); // skip non-recurring testcases if (!parser.incidence()->recurs()) { continue; } QTest::newRow(qPrintable(testData)) << parser.rangeStart() << parser.rangeEnd() << parser.eventData().first() << parser.incidence() << parser.akonadiId() << parser.eventData(); } } void EventDataVisitorTest::testExplodeIncidenceOccurences() { QFETCH(QDate, rangeStart); QFETCH(QDate, rangeEnd); QFETCH(CalendarEvents::EventData, baseEventData); QFETCH(KCalCore::Incidence::Ptr, incidence); QFETCH(qint64, akonadiItemId); QFETCH(QVector, expectedEventData); FakePimDataSource source; source.setAkonadiIdForIncidence(incidence, akonadiItemId); TestableEventDataVisitor visitor(&source, rangeStart, rangeEnd); bool ok = false; const auto results = visitor.callExplodeIncidenceOccurences(baseEventData, incidence, ok); QVERIFY(ok); QCOMPARE(results.size(), expectedEventData.size()); for (int i = 0; i < results.size(); ++i) { QVERIFY(TestUtils::compareEventData(results[i], expectedEventData[i])); } } void EventDataVisitorTest::testEventDataVisitor_data() { QTest::addColumn("rangeStart"); QTest::addColumn("rangeEnd"); QTest::addColumn("incidence"); QTest::addColumn("akonadiItemId"); QTest::addColumn >("expectedResults"); const auto allTestData = TestDataParser::allTestData(); for (const auto &testData : allTestData) { TestDataParser parser(testData); QTest::newRow(qPrintable(testData)) << parser.rangeStart() << parser.rangeEnd() << parser.incidence() << parser.akonadiId() << parser.eventData(); } } void EventDataVisitorTest::testEventDataVisitor() { QFETCH(QDate, rangeStart); QFETCH(QDate, rangeEnd); QFETCH(KCalCore::Incidence::Ptr, incidence); QFETCH(qint64, akonadiItemId); QFETCH(QVector, expectedResults); FakePimDataSource source; source.setAkonadiIdForIncidence(incidence, akonadiItemId); TestableEventDataVisitor visitor(&source, rangeStart, rangeEnd); QVERIFY(visitor.act(incidence)); const auto &results = visitor.results(); QCOMPARE(results.size(), expectedResults.size()); auto resultValues = results.values(); std::sort(resultValues.begin(), resultValues.end(), std::less()); for (int i = 0; i < resultValues.size(); ++i) { const auto &result = resultValues[i]; const auto &expectedResult = expectedResults[i]; QVERIFY(TestUtils::compareEventData(result, expectedResult)); } } void EventDataVisitorTest::testEventDataIdVisitor_data() { QTest::addColumn("rangeStart"); QTest::addColumn("rangeEnd"); QTest::addColumn("incidence"); QTest::addColumn("akonadiItemId"); QTest::addColumn("expectedUids"); const auto allTestData = TestDataParser::allTestData(); for (const auto &testData : allTestData) { TestDataParser parser(testData, true); QStringList uids; - Q_FOREACH (const auto &ed, parser.eventData()) { + for (const auto &ed : parser.eventData()) { uids.push_back(ed.uid()); } QTest::newRow(qPrintable(testData)) << parser.rangeStart() << parser.rangeEnd() << parser.incidence() << parser.akonadiId() << uids; } } void EventDataVisitorTest::testEventDataIdVisitor() { QFETCH(QDate, rangeStart); QFETCH(QDate, rangeEnd); QFETCH(KCalCore::Incidence::Ptr, incidence); QFETCH(qint64, akonadiItemId); QFETCH(QStringList, expectedUids); FakePimDataSource source; source.setAkonadiIdForIncidence(incidence, akonadiItemId); TestableEventDataIdVisitor visitor(&source, rangeStart, rangeEnd); QVERIFY(visitor.act(incidence)); auto results = visitor.results(); std::sort(results.begin(), results.end()); std::sort(expectedUids.begin(), expectedUids.end()); QCOMPARE(results, expectedUids); } QTEST_MAIN(EventDataVisitorTest) diff --git a/plugins/plasma/pimeventsplugin/autotests/pimeventsplugintest.cpp b/plugins/plasma/pimeventsplugin/autotests/pimeventsplugintest.cpp index 9a00e80a..25c466e5 100644 --- a/plugins/plasma/pimeventsplugin/autotests/pimeventsplugintest.cpp +++ b/plugins/plasma/pimeventsplugin/autotests/pimeventsplugintest.cpp @@ -1,265 +1,265 @@ /* * Copyright (C) 2016 Daniel Vrátil * * 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include "pimeventsplugintest.h" #include "fakepimdatasource.h" #include "testdataparser.h" #include "../pimeventsplugin.h" #include "testutils.h" #include #include Q_DECLARE_METATYPE(DateEventDataHash) Q_DECLARE_METATYPE(CalendarEvents::EventData) void PimEventsPluginTest::initTestCase() { qputenv("TZ", "Europe/Berlin"); qRegisterMetaType("QMultiHash"); qRegisterMetaType("CalendarEvents::EventData"); } bool PimEventsPluginTest::compareEventDataHashes(const DateEventDataHash &actual, const DateEventDataHash &expected) { COMPARE(actual.size(), expected.size()); - Q_FOREACH (const QDate &resultKey, actual.uniqueKeys()) { + for (const QDate &resultKey : actual.uniqueKeys()) { VERIFY(expected.contains(resultKey)); auto resultValues = actual.values(resultKey); auto expectedValues = expected.values(resultKey); COMPARE(resultValues.size(), expectedValues.size()); std::sort(resultValues.begin(), resultValues.end(), std::less()); std::sort(expectedValues.begin(), expectedValues.end(), std::less()); COMPARE(resultValues, expectedValues); } return true; } DateEventDataHash PimEventsPluginTest::populateCalendar(FakePimDataSource *source, bool uniqueEventData) { const QStringList allData = TestDataParser::allTestData(); DateEventDataHash expectedData; for (const QString &data : allData) { TestDataParser parser(data, true); if (parser.rangeEnd() < QDate(2016, 5, 1) || parser.rangeStart() > QDate(2016, 5, 31)) { continue; } const KCalCore::Event::Ptr event = parser.incidence().dynamicCast(); if (event) { source->setAkonadiIdForIncidence(event, parser.akonadiId()); source->calendar()->addEvent(event); Q_FOREACH (const CalendarEvents::EventData &dt, parser.eventData()) { if (uniqueEventData) { expectedData.insert(dt.startDateTime().date(), dt); } else { QDate d = dt.startDateTime().date(); while (d <= dt.endDateTime().date()) { expectedData.insert(d, dt); d = d.addDays(1); } } } } } return expectedData; } QVector PimEventsPluginTest::findEventData(const KCalCore::Event::Ptr &event, const DateEventDataHash &allData) { QVector data; for (auto it = allData.cbegin(), end = allData.cend(); it != end; ++it) { // This is a very naive check if (it->title() == event->summary() && it->description() == event->description() && it->isAllDay() == event->allDay()) { data.push_back((*it)); } } return data; } void PimEventsPluginTest::testLoadEventsForDataRange() { FakePimDataSource source; const DateEventDataHash expectedData = populateCalendar(&source, false); PimEventsPlugin plugin(&source); QSignalSpy dataReadySpy(&plugin, &PimEventsPlugin::dataReady); QVERIFY(dataReadySpy.isValid()); plugin.loadEventsForDateRange(QDate(2016, 5, 1), QDate(2016, 5, 31)); QCOMPARE(dataReadySpy.size(), 1); const auto results = dataReadySpy.takeFirst().first().value(); QVERIFY(compareEventDataHashes(results, expectedData)); plugin.loadEventsForDateRange(QDate(2016, 1, 1), QDate(2016, 1, 30)); QCOMPARE(dataReadySpy.size(), 0); } void PimEventsPluginTest::testEventAdded() { const QStringList allData = TestDataParser::allTestData(); FakePimDataSource source; PimEventsPlugin plugin(&source); QSignalSpy dataReadySpy(&plugin, &PimEventsPlugin::dataReady); QVERIFY(dataReadySpy.isValid()); plugin.loadEventsForDateRange(QDate(2016, 5, 1), QDate(2016, 5, 31)); QCOMPARE(dataReadySpy.size(), 0); - Q_FOREACH (const QString &data, allData) { + for (const QString &data : allData) { TestDataParser parser(data, true); if (parser.rangeEnd() < QDate(2016, 5, 1) || parser.rangeStart() > QDate(2016, 5, 31)) { continue; } const KCalCore::Event::Ptr event = parser.incidence().dynamicCast(); if (event) { source.setAkonadiIdForIncidence(event, parser.akonadiId()); source.calendar()->addEvent(event); DateEventDataHash expectedData; - Q_FOREACH (const CalendarEvents::EventData &dt, parser.eventData()) { + for (const CalendarEvents::EventData &dt : parser.eventData()) { QDate d = dt.startDateTime().date(); while (d <= dt.endDateTime().date()) { expectedData.insert(d, dt); d = d.addDays(1); } } QCOMPARE(dataReadySpy.size(), 1); const auto results = dataReadySpy.takeFirst().first().value(); QVERIFY(compareEventDataHashes(results, expectedData)); } } } void PimEventsPluginTest::testEventModified() { FakePimDataSource source; PimEventsPlugin plugin(&source); QSignalSpy eventModifiedSpy(&plugin, &PimEventsPlugin::eventModified); QVERIFY(eventModifiedSpy.isValid()); // Populate model const auto allData = populateCalendar(&source, true); // We don't care about the result of this, we just need to have mStart and // mEnd set plugin.loadEventsForDateRange(QDate(2016, 5, 1), QDate(2016, 5, 31)); // Non-recurring event { QVERIFY(eventModifiedSpy.isEmpty()); KCalCore::Event::Ptr event = source.calendar()->event(QStringLiteral("4d7fdd2c-2d3a-4ecf-8964-00eb92225209")); QVERIFY(event); const auto expectedData = findEventData(event, allData); QCOMPARE(expectedData.size(), 1); event->setSummary(QStringLiteral("TEST")); QVERIFY(source.calendar()->addEvent(event)); QCOMPARE(eventModifiedSpy.size(), 1); const auto result = eventModifiedSpy.takeFirst().first().value(); // TODO: Test for other property changes too? QCOMPARE(result.title(), event->summary()); QCOMPARE(result.uid(), expectedData[0].uid()); } // Recurring event { QVERIFY(eventModifiedSpy.isEmpty()); KCalCore::Event::Ptr event = source.calendar()->event(QStringLiteral("69971015-fe9c-4800-a20e-d46bafa24e41")); QVERIFY(event); auto expectedData = findEventData(event, allData); event->setSummary(QStringLiteral("TEST2")); QVERIFY(source.calendar()->addEvent(event)); QCOMPARE(eventModifiedSpy.size(), expectedData.size()); while (!eventModifiedSpy.isEmpty()) { const auto args = eventModifiedSpy.takeFirst(); const auto &resultData = args[0].value(); const auto expected = std::find_if(expectedData.begin(), expectedData.end(), [resultData](const CalendarEvents::EventData &e) { return e.uid() == resultData.uid(); }); QVERIFY(expected != expectedData.end()); expectedData.erase(expected); QCOMPARE(resultData.title(), QString::fromLatin1("TEST2")); } QVERIFY(expectedData.isEmpty()); } } void PimEventsPluginTest::testEventRemoved() { FakePimDataSource source; PimEventsPlugin plugin(&source); QSignalSpy eventRemovedSpy(&plugin, &PimEventsPlugin::eventRemoved); QVERIFY(eventRemovedSpy.isValid()); const auto allData = populateCalendar(&source, true); // We don't care about the result of this, we just need to have mStart and // mEnd set plugin.loadEventsForDateRange(QDate(2016, 5, 1), QDate(2016, 5, 31)); // Non-recurring event { QVERIFY(eventRemovedSpy.isEmpty()); const KCalCore::Event::Ptr event = source.calendar()->event(QStringLiteral("4d7fdd2c-2d3a-4ecf-8964-00eb92225209")); QVERIFY(event); const auto expectedData = findEventData(event, allData); QCOMPARE(expectedData.size(), 1); QVERIFY(source.calendar()->deleteEvent(event)); QCOMPARE(eventRemovedSpy.size(), 1); const auto result = eventRemovedSpy.takeFirst().first().toString(); QCOMPARE(result, expectedData[0].uid()); } // Recurring event { QVERIFY(eventRemovedSpy.isEmpty()); KCalCore::Event::Ptr event = source.calendar()->event(QStringLiteral("69971015-fe9c-4800-a20e-d46bafa24e41")); QVERIFY(event); auto expectedData = findEventData(event, allData); QVERIFY(source.calendar()->deleteEvent(event)); QCOMPARE(eventRemovedSpy.size(), expectedData.size()); while (!eventRemovedSpy.isEmpty()) { const QString resultUid = eventRemovedSpy.takeFirst().first().toString(); const auto expected = std::find_if(expectedData.begin(), expectedData.end(), [resultUid](const CalendarEvents::EventData &e) { return e.uid() == resultUid; }); QVERIFY(expected != expectedData.end()); expectedData.erase(expected); } QVERIFY(expectedData.isEmpty()); } } QTEST_MAIN(PimEventsPluginTest) diff --git a/plugins/plasma/pimeventsplugin/pimeventsplugin.cpp b/plugins/plasma/pimeventsplugin/pimeventsplugin.cpp index d1ad2a11..d4893af9 100644 --- a/plugins/plasma/pimeventsplugin/pimeventsplugin.cpp +++ b/plugins/plasma/pimeventsplugin/pimeventsplugin.cpp @@ -1,114 +1,114 @@ /* * Copyright (C) 2016 Daniel Vrátil * * 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include "pimeventsplugin.h" #include "eventdatavisitor.h" #include "akonadipimdatasource.h" #include "pimeventsplugin_debug.h" PimEventsPlugin::PimEventsPlugin(QObject *parent) : PimEventsPlugin(new AkonadiPimDataSource(), parent) { static_cast(mDataSource)->setParent(this); } PimEventsPlugin::PimEventsPlugin(PimDataSource *dataSource, QObject *parent) : CalendarEvents::CalendarEventsPlugin(parent) , mDataSource(dataSource) { qCDebug(PIMEVENTSPLUGIN_LOG) << "PIM Events Plugin activated"; dataSource->calendar()->registerObserver(this); } PimEventsPlugin::~PimEventsPlugin() { qCDebug(PIMEVENTSPLUGIN_LOG) << "PIM Events Plugin deactivated"; } void PimEventsPlugin::loadEventsForDateRange(const QDate &startDate, const QDate &endDate) { mStart = startDate; mEnd = endDate; int eventsCount = 0, eventDataCount = 0; { EventDataVisitor visitor(mDataSource, startDate, endDate); const KCalCore::Event::List events = mDataSource->calendar()->events(startDate, endDate); eventsCount = events.count(); if (visitor.act(events)) { eventDataCount = visitor.results().count(); Q_EMIT dataReady(visitor.results()); } } int todosCount = 0, todoDataCount = 0; { EventDataVisitor visitor(mDataSource, startDate, endDate); const KCalCore::Todo::List todos = mDataSource->calendar()->todos(startDate, endDate); todosCount = todos.count(); if (visitor.act(todos)) { todoDataCount = visitor.results().count(); Q_EMIT dataReady(visitor.results()); } } qCDebug(PIMEVENTSPLUGIN_LOG) << "Range:" << startDate.toString(Qt::ISODate) << "-" << endDate.toString(Qt::ISODate) << "Events:" << eventsCount << "EventData:" << eventDataCount << "Todos:" << todosCount << "TodoData:" << todoDataCount; } void PimEventsPlugin::calendarIncidenceAdded(const KCalCore::Incidence::Ptr &incidence) { if (!mStart.isValid() || !mEnd.isValid()) { // Don't bother with changes that happen before the applet starts populating data return; } EventDataVisitor visitor(mDataSource, mStart, mEnd); if (visitor.act(incidence)) { Q_EMIT dataReady(visitor.results()); } } void PimEventsPlugin::calendarIncidenceChanged(const KCalCore::Incidence::Ptr &incidence) { if (!mStart.isValid() || !mEnd.isValid()) { return; } EventDataVisitor visitor(mDataSource, mStart, mEnd); if (visitor.act(incidence)) { - Q_FOREACH (const auto &ed, visitor.results()) { + for (const auto &ed : visitor.results()) { Q_EMIT eventModified(ed); } } } void PimEventsPlugin::calendarIncidenceAboutToBeDeleted(const KCalCore::Incidence::Ptr &incidence) { if (!mStart.isValid() || !mEnd.isValid()) { return; } EventDataIdVisitor visitor(mDataSource, mStart, mEnd); if (visitor.act(incidence)) { - Q_FOREACH (const QString &uid, visitor.results()) { + for (const QString &uid : visitor.results()) { Q_EMIT eventRemoved(uid); } } }