Commit 428d9320 authored by Volker Krause's avatar Volker Krause
Browse files

Add a generic filter match implementation for QObject and Q_GADGET types

This removes duplicate code (ical, ERA SSB), enables more fields to filter
on (PkPass) and/or adds filtering to types that previously didn't support
this yet (UIC 918.3, VDV).
parent 679c24f7
Pipeline #61667 passed with stages
in 12 minutes and 7 seconds
......@@ -28,6 +28,7 @@ struct OwnedPtr {
inline OwnedPtr() = default;
inline OwnedPtr(T* _ptr) : ptr(_ptr) {}
inline operator T*() const { return ptr; }
inline T* operator->() const { return ptr; }
T *ptr = nullptr;
};
}
......@@ -189,4 +190,4 @@ private:
}
Q_DECLARE_METATYPE(KItinerary::ExtractorDocumentNode)
Q_DECLARE_SMART_POINTER_METATYPE(KItinerary::Internal::OwnedPtr)
......@@ -5,10 +5,12 @@
*/
#include "extractordocumentprocessor.h"
#include "extractorfilter.h"
#include "extractorresult.h"
#include <QJSEngine>
#include <QJSValue>
#include <QMetaProperty>
using namespace KItinerary;
......@@ -46,9 +48,30 @@ void ExtractorDocumentProcessor::preExtract([[maybe_unused]] ExtractorDocumentNo
{
}
bool ExtractorDocumentProcessor::matches([[maybe_unused]] const ExtractorFilter &filter, [[maybe_unused]] const ExtractorDocumentNode &node) const
bool ExtractorDocumentProcessor::matches(const ExtractorFilter &filter, const ExtractorDocumentNode &node) const
{
return false;
// QObject content
if (node.content().canConvert<QObject*>()) {
const auto obj = node.content().value<QObject*>();
if (!obj) {
return false;
}
const auto value = obj->property(filter.fieldName().toUtf8().constData());
return filter.matches(value.toString());
}
// Q_GADGET content
const auto mo = QMetaType(node.content().userType()).metaObject();
if (!mo) {
return false;
}
const auto propIdx = mo->indexOfProperty(filter.fieldName().toUtf8().constData());
if (propIdx < 0) {
return false;
}
const auto prop = mo->property(propIdx);
const auto value = prop.readOnGadget(node.content().constData());
return filter.matches(value.toString());
}
void ExtractorDocumentProcessor::postExtract([[maybe_unused]] ExtractorDocumentNode &node) const
......
......@@ -54,7 +54,7 @@ public:
virtual void preExtract(ExtractorDocumentNode &node, const ExtractorEngine *engine) const;
/** Checks whether the given @p filter matches @p node.
* The default implementation returns @c false unconditionally.
* The default implementation can handle QObject and Q_GADGET types via Qt's property system.
*/
virtual bool matches(const ExtractorFilter &filter, const ExtractorDocumentNode &node) const;
......
......@@ -78,17 +78,6 @@ void IcalCalendarProcessor::expandNode(ExtractorDocumentNode &node, const Extrac
#endif
}
bool IcalCalendarProcessor::matches(const ExtractorFilter &filter, const ExtractorDocumentNode &node) const
{
#ifdef HAVE_KCAL
const auto cal = node.content<KCalendarCore::Calendar::Ptr>();
const auto value = cal->property(filter.fieldName().toUtf8().constData());
return filter.matches(value.toString());
#else
return false;
#endif
}
bool IcalEventProcessor::matches(const ExtractorFilter &filter, const ExtractorDocumentNode &node) const
{
......
......@@ -17,7 +17,6 @@ public:
bool canHandleData(const QByteArray &encodedData, QStringView fileName) const override;
ExtractorDocumentNode createNodeFromData(const QByteArray &encodedData) const override;
void expandNode(ExtractorDocumentNode &node, const ExtractorEngine *engine) const override;
bool matches(const ExtractorFilter &filter, const ExtractorDocumentNode &node) const override;
};
/** Processor for ical calendar events. */
......
......@@ -86,18 +86,6 @@ void PkPassDocumentProcessor::destroyNode(ExtractorDocumentNode &node) const
destroyIfOwned<KPkPass::Pass>(node);
}
bool PkPassDocumentProcessor::matches(const ExtractorFilter &filter, const ExtractorDocumentNode &node) const
{
const auto pass = node.content<KPkPass::Pass*>();
QString value;
if (filter.fieldName() == QLatin1String("passTypeIdentifier")) {
value = pass->passTypeIdentifier();
} else {
return false;
}
return filter.matches(value);
}
QJSValue PkPassDocumentProcessor::contentToScriptValue(const ExtractorDocumentNode &node, QJSEngine *engine) const
{
return engine->toScriptValue(node.content<KPkPass::Pass*>());
......
......@@ -19,7 +19,6 @@ public:
ExtractorDocumentNode createNodeFromContent(const QVariant &decodedData) const override;
void expandNode(ExtractorDocumentNode &node, const ExtractorEngine *engine) const override;
void preExtract(ExtractorDocumentNode &node, const ExtractorEngine *engine) const override;
bool matches(const ExtractorFilter &filter, const ExtractorDocumentNode &node) const override;
QJSValue contentToScriptValue(const ExtractorDocumentNode &node, QJSEngine *engine) const override;
void postExtract(ExtractorDocumentNode &node) const override;
void destroyNode(ExtractorDocumentNode &node) const override;
......
......@@ -9,10 +9,6 @@
#include "era/ssbv1ticket.h"
#include "era/ssbv3ticket.h"
#include <KItinerary/ExtractorFilter>
#include <QMetaProperty>
using namespace KItinerary;
bool SsbDocumentProcessor::canHandleData(const QByteArray &encodedData, [[maybe_unused]] QStringView fileName) const
......@@ -36,19 +32,3 @@ ExtractorDocumentNode SsbDocumentProcessor::createNodeFromData(const QByteArray
}
return node;
}
bool SsbDocumentProcessor::matches(const ExtractorFilter &filter, const ExtractorDocumentNode &node) const
{
const auto ticket = node.content();
const auto mo = QMetaType(ticket.userType()).metaObject();
if (!mo) {
return false;
}
const auto propIdx = mo->indexOfProperty(filter.fieldName().toUtf8().constData());
if (propIdx < 0) {
return false;
}
const auto prop = mo->property(propIdx);
const auto value = prop.readOnGadget(ticket.constData());
return filter.matches(value.toString());
}
......@@ -17,7 +17,6 @@ class SsbDocumentProcessor : public ExtractorDocumentProcessor
public:
bool canHandleData(const QByteArray &encodedData, QStringView fileName) const override;
ExtractorDocumentNode createNodeFromData(const QByteArray &encodedData) const override;
bool matches(const KItinerary::ExtractorFilter &filter, const ExtractorDocumentNode &node) const override;
};
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment