diff --git a/examples/todos/src/Bindings.cpp b/examples/todos/src/Bindings.cpp index ed76eab..2ca8fc1 100644 --- a/examples/todos/src/Bindings.cpp +++ b/examples/todos/src/Bindings.cpp @@ -1,301 +1,312 @@ /* generated by rust_qt_binding_generator */ #include "Bindings.h" namespace { struct option_quintptr { public: quintptr value; bool some; operator QVariant() const { if (some) { return QVariant::fromValue(value); } return QVariant(); } }; static_assert(std::is_pod::value, "option_quintptr must be a POD type."); typedef void (*qstring_set)(QString* val, const char* utf8, int nbytes); void set_qstring(QString* val, const char* utf8, int nbytes) { *val = QString::fromUtf8(utf8, nbytes); } struct qmodelindex_t { int row; quintptr id; }; inline QVariant cleanNullQVariant(const QVariant& v) { return (v.isNull()) ?QVariant() :v; } inline void todosActiveCountChanged(Todos* o) { emit o->activeCountChanged(); } inline void todosCountChanged(Todos* o) { emit o->countChanged(); } } extern "C" { bool todos_data_completed(const Todos::Private*, int); bool todos_set_data_completed(Todos::Private*, int, bool); void todos_data_description(const Todos::Private*, int, QString*, qstring_set); bool todos_set_data_description(Todos::Private*, int, const ushort* s, int len); void todos_sort(Todos::Private*, unsigned char column, Qt::SortOrder order = Qt::AscendingOrder); int todos_row_count(const Todos::Private*); bool todos_insert_rows(Todos::Private*, int, int); bool todos_remove_rows(Todos::Private*, int, int); bool todos_can_fetch_more(const Todos::Private*); void todos_fetch_more(Todos::Private*); } int Todos::columnCount(const QModelIndex &parent) const { return (parent.isValid()) ? 0 : 1; } bool Todos::hasChildren(const QModelIndex &parent) const { return rowCount(parent) > 0; } int Todos::rowCount(const QModelIndex &parent) const { return (parent.isValid()) ? 0 : todos_row_count(m_d); } bool Todos::insertRows(int row, int count, const QModelIndex &) { return todos_insert_rows(m_d, row, count); } bool Todos::removeRows(int row, int count, const QModelIndex &) { return todos_remove_rows(m_d, row, count); } QModelIndex Todos::index(int row, int column, const QModelIndex &parent) const { if (!parent.isValid() && row >= 0 && row < rowCount(parent) && column >= 0 && column < 1) { return createIndex(row, column, (quintptr)row); } return QModelIndex(); } QModelIndex Todos::parent(const QModelIndex &) const { return QModelIndex(); } bool Todos::canFetchMore(const QModelIndex &parent) const { return (parent.isValid()) ? 0 : todos_can_fetch_more(m_d); } void Todos::fetchMore(const QModelIndex &parent) { if (!parent.isValid()) { todos_fetch_more(m_d); } } void Todos::sort(int column, Qt::SortOrder order) { todos_sort(m_d, column, order); } Qt::ItemFlags Todos::flags(const QModelIndex &i) const { auto flags = QAbstractItemModel::flags(i); if (i.column() == 0) { flags |= Qt::ItemIsEditable; } return flags; } bool Todos::completed(int row) const { return todos_data_completed(m_d, row); } bool Todos::setCompleted(int row, bool value) { bool set = false; set = todos_set_data_completed(m_d, row, value); if (set) { QModelIndex index = createIndex(row, 0, row); emit dataChanged(index, index); } return set; } QString Todos::description(int row) const { QString s; todos_data_description(m_d, row, &s, set_qstring); return s; } bool Todos::setDescription(int row, const QString& value) { bool set = false; set = todos_set_data_description(m_d, row, value.utf16(), value.length()); if (set) { QModelIndex index = createIndex(row, 0, row); emit dataChanged(index, index); } return set; } QVariant Todos::data(const QModelIndex &index, int role) const { Q_ASSERT(rowCount(index.parent()) > index.row()); switch (index.column()) { case 0: switch (role) { case Qt::UserRole + 0: return QVariant::fromValue(completed(index.row())); case Qt::UserRole + 1: return QVariant::fromValue(description(index.row())); } } return QVariant(); } +int Todos::role(const char* name) const { + auto names = roleNames(); + auto i = names.constBegin(); + while (i != names.constEnd()) { + if (i.value() == name) { + return i.key(); + } + ++i; + } + return -1; +} QHash Todos::roleNames() const { QHash names = QAbstractItemModel::roleNames(); names.insert(Qt::UserRole + 0, "completed"); names.insert(Qt::UserRole + 1, "description"); return names; } QVariant Todos::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation != Qt::Horizontal) { return QVariant(); } return m_headerData.value(qMakePair(section, (Qt::ItemDataRole)role), role == Qt::DisplayRole ?QString::number(section + 1) :QVariant()); } bool Todos::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role) { if (orientation != Qt::Horizontal) { return false; } m_headerData.insert(qMakePair(section, (Qt::ItemDataRole)role), value); return true; } bool Todos::setData(const QModelIndex &index, const QVariant &value, int role) { if (index.column() == 0) { if (role == Qt::UserRole + 0) { if (value.canConvert(qMetaTypeId())) { return setCompleted(index.row(), value.value()); } } if (role == Qt::UserRole + 1) { if (value.canConvert(qMetaTypeId())) { return setDescription(index.row(), value.value()); } } } return false; } extern "C" { Todos::Private* todos_new(Todos*, void (*)(Todos*), void (*)(Todos*), void (*)(const Todos*), void (*)(Todos*, quintptr, quintptr), void (*)(Todos*), void (*)(Todos*), void (*)(Todos*, int, int), void (*)(Todos*), void (*)(Todos*, int, int), void (*)(Todos*)); void todos_free(Todos::Private*); quint64 todos_active_count_get(const Todos::Private*); quint64 todos_count_get(const Todos::Private*); void todos_add(Todos::Private*, const ushort*, int); void todos_clear_completed(Todos::Private*); bool todos_remove(Todos::Private*, quint64); void todos_set_all(Todos::Private*, bool); }; Todos::Todos(bool /*owned*/, QObject *parent): QAbstractItemModel(parent), m_d(0), m_ownsPrivate(false) { initHeaderData(); } Todos::Todos(QObject *parent): QAbstractItemModel(parent), m_d(todos_new(this, todosActiveCountChanged, todosCountChanged, [](const Todos* o) { emit o->newDataReady(QModelIndex()); }, [](Todos* o, quintptr first, quintptr last) { o->dataChanged(o->createIndex(first, 0, first), o->createIndex(last, 0, last)); }, [](Todos* o) { o->beginResetModel(); }, [](Todos* o) { o->endResetModel(); }, [](Todos* o, int first, int last) { o->beginInsertRows(QModelIndex(), first, last); }, [](Todos* o) { o->endInsertRows(); }, [](Todos* o, int first, int last) { o->beginRemoveRows(QModelIndex(), first, last); }, [](Todos* o) { o->endRemoveRows(); } )), m_ownsPrivate(true) { connect(this, &Todos::newDataReady, this, [this](const QModelIndex& i) { this->fetchMore(i); }, Qt::QueuedConnection); initHeaderData(); } Todos::~Todos() { if (m_ownsPrivate) { todos_free(m_d); } } void Todos::initHeaderData() { } quint64 Todos::activeCount() const { return todos_active_count_get(m_d); } quint64 Todos::count() const { return todos_count_get(m_d); } void Todos::add(const QString& description) { return todos_add(m_d, description.utf16(), description.size()); } void Todos::clearCompleted() { return todos_clear_completed(m_d); } bool Todos::remove(quint64 index) { return todos_remove(m_d, index); } void Todos::setAll(bool completed) { return todos_set_all(m_d, completed); } diff --git a/examples/todos/src/Bindings.h b/examples/todos/src/Bindings.h index 6f2cab9..cbd6028 100644 --- a/examples/todos/src/Bindings.h +++ b/examples/todos/src/Bindings.h @@ -1,62 +1,63 @@ /* generated by rust_qt_binding_generator */ #ifndef BINDINGS_H #define BINDINGS_H #include #include class Todos; class Todos : public QAbstractItemModel { Q_OBJECT public: class Private; private: Private * m_d; bool m_ownsPrivate; Q_PROPERTY(quint64 activeCount READ activeCount NOTIFY activeCountChanged FINAL) Q_PROPERTY(quint64 count READ count NOTIFY countChanged FINAL) explicit Todos(bool owned, QObject *parent); public: explicit Todos(QObject *parent = nullptr); ~Todos(); quint64 activeCount() const; quint64 count() const; Q_INVOKABLE void add(const QString& description); Q_INVOKABLE void clearCompleted(); Q_INVOKABLE bool remove(quint64 index); Q_INVOKABLE void setAll(bool completed); int columnCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; QModelIndex parent(const QModelIndex &index) const override; bool hasChildren(const QModelIndex &parent = QModelIndex()) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; bool canFetchMore(const QModelIndex &parent) const override; void fetchMore(const QModelIndex &parent) override; Qt::ItemFlags flags(const QModelIndex &index) const override; void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override; + int role(const char* name) const; QHash roleNames() const override; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole) override; Q_INVOKABLE bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; Q_INVOKABLE bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; Q_INVOKABLE bool completed(int row) const; Q_INVOKABLE bool setCompleted(int row, bool value); Q_INVOKABLE QString description(int row) const; Q_INVOKABLE bool setDescription(int row, const QString& value); signals: // new data is ready to be made available to the model with fetchMore() void newDataReady(const QModelIndex &parent) const; private: QHash, QVariant> m_headerData; void initHeaderData(); signals: void activeCountChanged(); void countChanged(); }; #endif // BINDINGS_H