Commit 08b3a71f authored by EXT Arnaud Clère's avatar EXT Arnaud Clère
Browse files

WIP QMetaObject support

parent b47a4442
......@@ -45,6 +45,7 @@ gcc:QMAKE_CXXFLAGS += -ftemplate-backtrace-limit=0
#QMAKE_EXTRA_COMPILERS += protoc
SOURCES += \
data.cpp \
main.cpp
HEADERS += \
......@@ -54,7 +55,8 @@ HEADERS += \
QVariant_impl.h \
QModel_impl.h \
QData_impl.h \
QXml_impl.h
QXml_impl.h \
data.h
DISTFILES += \
README.md \
......
......@@ -719,7 +719,7 @@ public:
QLogger() : Cursor(s_impl) {}
};
QAtomicPointer<IWriter> QLogger::s_impl = nullptr;
// TODO in .cpp QAtomicPointer<IWriter> QLogger::s_impl = nullptr;
#include <functional>
......@@ -741,6 +741,44 @@ public:
// //////////////////////////////////////////////////////////////////////////
// QBind partial specializations (generic on TResult, usually not on v->mode() for dynamically-sized or builtin types)
#include <QtCore/qmetatype.h>
#include <QtCore/qmetaobject.h>
template<class T, class TResult>
TResult qbind(Val<TResult>&& v, T* t) {
auto rw = v->mode();
auto mo = T::staticMetaObject;
auto r = v.meta({{qmName,mo.className()}}).record();
for (int i = 0; i<mo.propertyCount(); i++) {
auto p = mo.property(i);
if (p.isStored()) {
if (rw==Read) {
QVariant pv;
r = r.bind(p.name(),pv);
/* TODO if (p.isEnumType()) keyToValue(pv.toString()) */
if ((!r && p.isResettable() && !p.resetOnGadget(t) )||
( r && !p.writeOnGadget(t, pv))) {
v->reportError("TODO");
}
}
if (rw==Write) {
QVariant pv = p.readOnGadget(t);
if (p.isEnumType() /*&& pv.canConvert<int>()*/) {
r = r.bind(p.name(), p.enumerator().valueToKey(pv.toInt()));
}
else {
r = r.bind(p.name(), pv);
}
}
else { Q_ASSERT_X(!v, Q_FUNC_INFO, "Unsupported v->mode()"); return v.null(); }
}
}
return r;
}
//! Default bind(Val<TResult>&&) based on static QMetaObject reflection
#define QBIND_GADGET_WITH_METAOBJECT(Class) template<class TResult> TResult bind(Val<TResult>&& v) { return qbind<Class,TResult>(std::move(v), this); }
template<typename T, class TResult> //=Cursor
struct QBind<QBindDefault<T>, TResult> {
static TResult bind(Val<TResult>&& v, QBindDefault<T>&& t) {
......
#include "data.h"
// for moc
#pragma once
#include <QtCore/qmetaobject.h>
#include "QBind_impl.h"
class Phone {
Q_GADGET
Q_PROPERTY(Type type MEMBER _t)
Q_PROPERTY(QString number MEMBER _n)
public:
QBIND_GADGET_WITH_METAOBJECT(Phone) // making it (de)serializable and printable using reflection
enum Type { Unknown=0, Mobile, Home, Office } type;
Q_ENUM(Type)
Phone(Type t=Unknown, QString n=QString()) : _t(t), _n(n) {}
private:
Type _t; QString _n;
};
......@@ -71,18 +71,7 @@
// Using Qt's meta-object system
class Phone {
Q_GADGET
public:
enum Type { Mobile, Home, Office } type;
Q_ENUM(Type)
Q_PROPERTY(Type type MEMBER _t)
Q_PROPERTY(QString number MEMBER _n)
private:
Type _t;
QString _n;
};
#include "data.h"
// Using an internal bind method
......@@ -851,6 +840,7 @@ int main(int argc, char *argv[])
QStandardItemModel matrixModel; QModelWriter<>(&matrixModel,false).meta({{qmSizes ,"4,3"}}).bind(transform);
QDialog dlg;
dlg.setWindowTitle(QString("Support: ")+Text(Phone{ Phone::Office, "+33 123" }));
auto layout = new QHBoxLayout(&dlg); dlg.setLayout(layout);
auto tree = new QTreeView (&dlg); layout->addWidget(tree ); tree ->setModel(& treeModel); for(int i=0; i<treeModel.columnCount(); i++) tree ->resizeColumnToContents(i);
auto table = new QTableView (&dlg); layout->addWidget(table ); table ->setModel(& tableModel); table ->resizeColumnsToContents();
......
Supports Markdown
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