Skip to content

Commit

Permalink
QskDataObjectBinder
Browse files Browse the repository at this point in the history
  • Loading branch information
ovenpasta committed Feb 23, 2024
1 parent 3902d05 commit 0f825ee
Show file tree
Hide file tree
Showing 6 changed files with 215 additions and 144 deletions.
2 changes: 1 addition & 1 deletion playground/models/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
# SPDX-License-Identifier: BSD-3-Clause
############################################################################

qsk_add_example(models Window.h Window.cpp QskDataControlMapper.cpp QskDataControlMapper.h main.cpp)
qsk_add_example(models QskModelObjectBinder.cpp QskModelObjectBinder.h Window.h Window.cpp main.cpp)

target_link_libraries(models PRIVATE Qt::Sql)
78 changes: 0 additions & 78 deletions playground/models/QskDataControlMapper.cpp

This file was deleted.

54 changes: 0 additions & 54 deletions playground/models/QskDataControlMapper.h

This file was deleted.

160 changes: 160 additions & 0 deletions playground/models/QskModelObjectBinder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
//
// Created by aldo on 27/01/21.
//

#include "QskModelObjectBinder.h"

#include <QAbstractItemModel>
#include <QPointer>
#include <qassert.h>

class QskModelObjectBinder::PrivateData
{
public:
PrivateData( )
{
}

struct Item {
Item() :valid(false), column(-1) {};
Item(QObject *obj, int column, const QByteArray& property)
: valid (true), object( obj ), column( column ), property( property )
{
};
bool valid;
QPointer< QObject > object;
int column;
QByteArray property;
};
void updateObjectProperty(Item & x)
{
Q_ASSERT( x.object != nullptr );
Q_ASSERT( ! x.property.isEmpty() );
x.object->setProperty(x.property,
m->index(modelIndex.row(),x.column).data(Qt::EditRole));
}

void updateAllObjects()
{
for (auto it = items.begin(); it != items.end(); ++it) {
updateObjectProperty(it.value());
}
}

void updateModelField(Item& x)
{
Q_ASSERT( x.valid );
Q_ASSERT( x.object != nullptr );
auto prop =x.object->property( x.property );
Q_ASSERT( prop.isValid() );

m->setData(m->index(modelIndex.row(),x.column),prop);
}

void updateModelFields()
{
for (auto it = items.begin(); it != items.end(); ++it)
{
updateModelField( it.value() );
}
}

public:
QMap<QObject*,Item> items;
QAbstractItemModel* m;
QPersistentModelIndex modelIndex;
};

static bool modelContainsIndex(const QModelIndex & idx, const QModelIndex & topLeft, const QModelIndex & bottomRight)
{
return idx.row() >= topLeft.row() && idx.row() <= bottomRight.row()
&& idx.column() >= topLeft.column() && idx.column() <= bottomRight.column();
}

QskModelObjectBinder::QskModelObjectBinder(QObject* parent)
: QObject( parent )
{
m_data=std::make_unique<PrivateData>( );
}

QskModelObjectBinder::QskModelObjectBinder(QAbstractItemModel *model, QObject* parent)
: QObject( parent )
{
m_data=std::make_unique<PrivateData>();
bindModel(model);
}


void QskModelObjectBinder::bindObject(QObject *obj, int column, const QByteArray &propertyName)
{
Q_ASSERT( obj != nullptr );

if(obj == nullptr)
return;

QMetaProperty prop;
auto meta = obj->metaObject();
if (propertyName.isEmpty())
{
prop = meta->userProperty();
}else
{
auto idx = meta->indexOfProperty( propertyName );
if(idx>=0)
{
prop=meta->property(idx);
}
}
Q_ASSERT(! prop.isValid());

PrivateData::Item item(obj,column,prop.name());
m_data->items[obj]=item;
}

void QskModelObjectBinder::unbindObject(QObject *obj)
{
m_data->items.remove(obj);
}

void QskModelObjectBinder::bindModel(QAbstractItemModel *model)
{
m_data->m=model;
m_data->modelIndex=QModelIndex();
if(model) {
connect(m_data->m,&QAbstractItemModel::dataChanged,this,
&QskModelObjectBinder::modelDataChanged);
}
}

void QskModelObjectBinder::modelDataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight, const QVector<int> &)
{
const int row = m_data->modelIndex.row();
for (auto it = m_data->items.begin(); it != m_data->items.end(); ++it) {
if (modelContainsIndex(m_data->m->index(row,it.value().column), topLeft, bottomRight)) {
m_data->updateObjectProperty(it.value());
}
}
}

void QskModelObjectBinder::selectRow( int row )
{
Q_ASSERT( m_data->m != nullptr );

if ( !m_data->m )
return;

m_data->modelIndex = m_data->m->index( row, 0 );
m_data->updateAllObjects();
}

int QskModelObjectBinder::currentRow() const
{
return m_data->modelIndex.row();
}

void QskModelObjectBinder::updateModel()
{
m_data->updateModelFields();
}

#include "moc_QskModelObjectBinder.cpp"
34 changes: 34 additions & 0 deletions playground/models/QskModelObjectBinder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#ifndef QSKDATACONTROLMAPPER_H
#define QSKDATACONTROLMAPPER_H

#include <QskControl.h>
#include <QAbstractItemModel>

class QskModelObjectBinder : public QObject {
Q_OBJECT

public:
QskModelObjectBinder(QObject *parent=nullptr);
QskModelObjectBinder(QAbstractItemModel* model, QObject *parent=nullptr);

void bindObject(QObject*, int column, const QByteArray &propertyName="");
void unbindObject(QObject*o);

void bindModel(QAbstractItemModel* model);

void selectRow(int row);
[[nodiscard]] int currentRow() const;

void updateModel();

private Q_SLOTS:
void modelDataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight, const QVector<int> &);

private:
class PrivateData;
std::unique_ptr< PrivateData > m_data;
};



#endif //QSKDATACONTROLMAPPER_H
Loading

0 comments on commit 0f825ee

Please sign in to comment.