/*
Copyright (C) 2019 Filippo Cucchetto.
Contact: https://github.com/filcuc/dotherside
This file is part of the DOtherSide library.
The DOtherSide library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the license, or (at your opinion) any later version.
The DOtherSide 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the DOtherSide library. If not, see .
*/
#pragma once
#include "DOtherSide/DosQAbstractItemModel.h"
#include "DOtherSide/DosQMetaObject.h"
namespace DOS {
template
class DosQAbstractItemModelWrapper : public QAbstractItemModel, public DosIQObjectImpl
{
public:
static const QMetaObject staticMetaObject;
/// Constructor
DosQAbstractItemModelWrapper(QObject *parent = nullptr);
/// Destructor
~DosQAbstractItemModelWrapper() override;
/// @see DosIQObjectImpl::metaObject
const QMetaObject *metaObject() const override;
/// @see DosIQObjectImpl::qt_metacall
int qt_metacall(QMetaObject::Call, int, void **) override;
/// @see DosIQObjectImpl::emitSignal
bool emitSignal(QObject *emitter, const QString &name, const std::vector &argumentsValues) override;
/// Return the qml registration type
static const QmlRegisterType &qmlRegisterType();
/// Sets the qml registration type
static void setQmlRegisterType(QmlRegisterType data);
/// Sets the static metaobject
static void setStaticMetaObject(const QMetaObject &metaObject);
/// Sets the qmlRegisterType id
static void setId(int id);
/// @see QAbstractItemModel::rowCount
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
/// @see QAbstractItemModel::columnCount
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
/// @see QAbstractItemModel::data
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
/// @see QAbstractItemModel::setData
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
/// @see QAbstractItemModel::flags
Qt::ItemFlags flags(const QModelIndex &index) const override;
/// @see QAbstractItemModel::headerData
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
/// @see QAbstractItemModel::roleNames
QHash roleNames() const override;
/// @see QAbstractItemModel::index
QModelIndex index(int row, int column, const QModelIndex &parent) const override;
/// @see QAbstractItemModel::parent
QModelIndex parent(const QModelIndex &child) const override;
private:
void *m_dObject;
QAbstractItemModel *m_impl;
static int m_id;
static QmlRegisterType m_data;
};
template
const QMetaObject DosQAbstractItemModelWrapper::staticMetaObject = QAbstractItemModel::staticMetaObject;
template
QmlRegisterType DosQAbstractItemModelWrapper::m_data;
template
int DosQAbstractItemModelWrapper::m_id = -1;
template
DosQAbstractItemModelWrapper::DosQAbstractItemModelWrapper(QObject *parent)
: QAbstractItemModel(parent)
, m_dObject(nullptr)
, m_impl(nullptr)
{
void *impl = nullptr;
m_data.createDObject(m_id, static_cast(this), &m_dObject, &impl);
beginResetModel();
m_impl = dynamic_cast(static_cast(impl));
QObject::connect(m_impl, &QAbstractItemModel::rowsAboutToBeInserted, this, &DosQAbstractItemModelWrapper::beginInsertRows);
QObject::connect(m_impl, &QAbstractItemModel::rowsInserted, this, &DosQAbstractItemModelWrapper::endInsertRows);
QObject::connect(m_impl, &QAbstractItemModel::rowsAboutToBeRemoved, this, &DosQAbstractItemModelWrapper::beginRemoveRows);
QObject::connect(m_impl, &QAbstractItemModel::rowsRemoved, this, &DosQAbstractItemModelWrapper::endRemoveRows);
QObject::connect(m_impl, &QAbstractItemModel::rowsAboutToBeMoved, this, &DosQAbstractItemModelWrapper::beginMoveRows);
QObject::connect(m_impl, &QAbstractItemModel::rowsMoved, this, &DosQAbstractItemModelWrapper::endMoveRows);
QObject::connect(m_impl, &QAbstractItemModel::columnsAboutToBeInserted, this, &DosQAbstractItemModelWrapper::beginInsertColumns);
QObject::connect(m_impl, &QAbstractItemModel::columnsInserted, this, &DosQAbstractItemModelWrapper::endInsertColumns);
QObject::connect(m_impl, &QAbstractItemModel::columnsAboutToBeRemoved, this, &DosQAbstractItemModelWrapper::beginRemoveColumns);
QObject::connect(m_impl, &QAbstractItemModel::columnsRemoved, this, &DosQAbstractItemModelWrapper::endRemoveColumns);
QObject::connect(m_impl, &QAbstractItemModel::columnsAboutToBeMoved, this, &DosQAbstractItemModelWrapper::beginMoveColumns);
QObject::connect(m_impl, &QAbstractItemModel::columnsMoved, this, &DosQAbstractItemModelWrapper::endMoveColumns);
QObject::connect(m_impl, &QAbstractItemModel::modelAboutToBeReset, this, &DosQAbstractItemModelWrapper::beginResetModel);
QObject::connect(m_impl, &QAbstractItemModel::modelReset, this, &DosQAbstractItemModelWrapper::endResetModel);
QObject::connect(m_impl, &QAbstractItemModel::dataChanged, this, &DosQAbstractItemModelWrapper::dataChanged);
QObject::connect(m_impl, &QAbstractItemModel::layoutAboutToBeChanged, this, &DosQAbstractItemModelWrapper::layoutAboutToBeChanged);
QObject::connect(m_impl, &QAbstractItemModel::layoutChanged, this, &DosQAbstractItemModelWrapper::layoutChanged);
endResetModel();
Q_ASSERT(m_dObject);
Q_ASSERT(m_impl);
}
template
DosQAbstractItemModelWrapper::~DosQAbstractItemModelWrapper()
{
m_data.deleteDObject(m_id, m_dObject);
m_dObject = nullptr;
delete m_impl;
m_impl = nullptr;
}
template
const QMetaObject *DosQAbstractItemModelWrapper::metaObject() const
{
Q_ASSERT(m_impl);
return m_impl->metaObject();
}
template
int DosQAbstractItemModelWrapper::qt_metacall(QMetaObject::Call call, int index, void **args)
{
Q_ASSERT(m_impl);
return m_impl->qt_metacall(call, index, args);
}
template
bool DosQAbstractItemModelWrapper::emitSignal(QObject *emitter, const QString &name, const std::vector &argumentsValues)
{
Q_ASSERT(m_impl);
return dynamic_cast(this)->emitSignal(this, name, argumentsValues);
}
template
void DosQAbstractItemModelWrapper::setQmlRegisterType(QmlRegisterType data)
{
m_data = std::move(data);
}
template
void DosQAbstractItemModelWrapper::setStaticMetaObject(const QMetaObject &metaObject)
{
*(const_cast(&staticMetaObject)) = metaObject;
}
template
void DosQAbstractItemModelWrapper::setId(int id)
{
m_id = id;
}
template
int DosQAbstractItemModelWrapper::rowCount(const QModelIndex &parent) const
{
Q_ASSERT(m_impl);
return m_impl->rowCount(parent);
}
template
int DosQAbstractItemModelWrapper::columnCount(const QModelIndex &parent) const
{
Q_ASSERT(m_impl);
return m_impl->columnCount(parent);
}
template
QVariant DosQAbstractItemModelWrapper::data(const QModelIndex &index, int role) const
{
Q_ASSERT(m_impl);
return m_impl->data(index, role);
}
template
bool DosQAbstractItemModelWrapper::setData(const QModelIndex &index, const QVariant &value, int role)
{
Q_ASSERT(m_impl);
return m_impl->setData(index, value, role);
}
template
Qt::ItemFlags DosQAbstractItemModelWrapper::flags(const QModelIndex &index) const
{
Q_ASSERT(m_impl);
return m_impl->flags(index);
}
template
QVariant DosQAbstractItemModelWrapper::headerData(int section, Qt::Orientation orientation, int role) const
{
Q_ASSERT(m_impl);
return m_impl->headerData(section, orientation, role);
}
template
QHash DosQAbstractItemModelWrapper::roleNames() const
{
Q_ASSERT(m_impl);
return m_impl->roleNames();
}
template
QModelIndex DosQAbstractItemModelWrapper::index(int row, int column, const QModelIndex &parent) const
{
Q_ASSERT(m_impl);
return m_impl->index(row, column, parent);
}
template
QModelIndex DosQAbstractItemModelWrapper::parent(const QModelIndex &child) const
{
Q_ASSERT(m_impl);
return m_impl->parent(child);
}
template
const QmlRegisterType &DosQAbstractItemModelWrapper::qmlRegisterType()
{
return m_data;
}
namespace DQAIMW {
template
using RegisterTypeQObject = DosQAbstractItemModelWrapper;
template
int dosQmlRegisterType(QmlRegisterType args)
{
RegisterTypeQObject::setQmlRegisterType(std::move(args));
const QmlRegisterType &type = RegisterTypeQObject::qmlRegisterType();
RegisterTypeQObject::setStaticMetaObject(*(type.staticMetaObject->metaObject()));
int result = qmlRegisterType>(type.uri.c_str(), type.major, type.minor, type.qml.c_str());
RegisterTypeQObject::setId(result);
return result;
}
template
struct DosQmlRegisterHelper {
static int Register(int i, QmlRegisterType args)
{
if (i > N)
return -1;
else if (i == N)
return dosQmlRegisterType(std::move(args));
else
return DosQmlRegisterHelper < N - 1 >::Register(i, std::move(args));
}
};
template<>
struct DosQmlRegisterHelper<0> {
static int Register(int i, QmlRegisterType args)
{
return i == 0 ? dosQmlRegisterType<0>(std::move(args)) : -1;
}
};
int dosQmlRegisterType(QmlRegisterType args)
{
static int i = 0;
return DosQmlRegisterHelper<35>::Register(i++, std::move(args));
}
template
using RegisterSingletonTypeQObject = DosQAbstractItemModelWrapper;
template
QObject *singletontype_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
{
return new RegisterSingletonTypeQObject();
}
template
int dosQmlRegisterSingletonType(QmlRegisterType args)
{
using Func = QObject * (*)(QQmlEngine *, QJSEngine *);
Func f = singletontype_provider;
RegisterSingletonTypeQObject::setQmlRegisterType(std::move(args));
const QmlRegisterType &type = RegisterSingletonTypeQObject::qmlRegisterType();
RegisterSingletonTypeQObject::setStaticMetaObject(*(type.staticMetaObject->metaObject()));
int result = qmlRegisterSingletonType>(type.uri.c_str(), type.major, type.minor, type.qml.c_str(), f);
RegisterSingletonTypeQObject::setId(result);
return result;
}
template
struct DosQmlRegisterSingletonHelper {
static int Register(int i, QmlRegisterType args)
{
if (i > N)
return -1;
else if (i == N)
return dosQmlRegisterSingletonType(std::move(args));
else
return DosQmlRegisterSingletonHelper < N - 1 >::Register(i, std::move(args));
}
};
template<>
struct DosQmlRegisterSingletonHelper<0> {
static int Register(int i, QmlRegisterType args)
{
return i == 0 ? dosQmlRegisterSingletonType<0>(std::move(args)) : -1;
}
};
int dosQmlRegisterSingletonType(QmlRegisterType args)
{
static int i = 0;
return DosQmlRegisterSingletonHelper<35>::Register(i++, std::move(args));
}
}
}