SXXXXXXX_PyDownloadFwViaSRIO/_OLD/Vecchia_app/FpgaBeamMeUp/Qg/qgpropertywidget.cpp.bak
2026-01-22 17:10:05 +01:00

399 lines
11 KiB
C++

#include "qgpropertywidget.h"
#include <QTreeView>
#include <QTreeWidgetItem>
#include <QStandardItemModel>
#include <QStandardItem>
#include <QWidget>
#include <QVBoxLayout>
#include <QLabel>
#include <QMetaObject>
#include <QMetaProperty>
#include <QMetaEnum>
#include <QStyledItemDelegate>
#include <QItemDelegate>
#include <QLineEdit>
#include <QCheckBox>
#include <QComboBox>
#include <QDialogButtonBox>
#include "mydebug.h"
class QgPropertyWidget::Implementation
{
public:
QWidget* w;
QLabel* lbl;
QVBoxLayout* ly;
QTreeView* t;
QStandardItemModel* m;
QObject* obj;
QDialogButtonBox* bb;
};
enum DelegateType
{
DT_Enum=QVariant::UserType+1,
DT_Checkbox,
DT_Combo
};
const int MyTypeRole = Qt::UserRole + 1;
class PropertyItem: public QStandardItem
{
public:
QObject& obj;
const QMetaObject& mt;
QMetaProperty mp;
int index;
QStandardItem& value;
QStandardItem& label;
virtual ~PropertyItem()
{
//MyDebug()<<"PropertyItem::~PropertyItem()";
}
PropertyItem(QObject& o, int i):
obj(o),
mt(*o.metaObject()),
mp(mt.property(i)),
index(i),
value(*this),
label(*new QStandardItem)
{
label.setData(mp.name(), Qt::DisplayRole);
label.setEditable(false);
QString description; //=mt.classInfo(mt.indexOfClassInfo("description")).value();
description+=QString(" (")+QString(mp.typeName())+QString(")");
label.setToolTip(description);
label.setData(MyTypeRole, reinterpret_cast<const unsigned long long>(&obj));
value.setData(reinterpret_cast<const unsigned long long>(this), MyTypeRole);
value.setEnabled(mp.isValid() && mp.isReadable());
value.setData("(invalid)", Qt::DisplayRole);
value.setEditable(false);
propertyInit();
}
virtual void propertyInit()
{
value.setEditable(mp.isWritable());
value.setData(mp.read(&obj), Qt::DisplayRole);
}
virtual QString displayText() const
{
return mp.read(&obj).toString();
}
virtual QWidget* createEditor(QWidget */*parent*/, const QStyleOptionViewItem &/*option*/, const QModelIndex &/*index*/) const
{
return 0;
}
virtual bool updateEditorGeometry(QWidget */*editor*/, const QStyleOptionViewItem &/*option*/, const QModelIndex &/*index*/) const
{
return false;
}
virtual bool onSetModelData(QWidget* /*editor*/, QAbstractItemModel */*model*/, const QModelIndex& /*index*/) const
{
obj.setProperty(mp.name(), value.data(Qt::DisplayRole));
return false;
}
virtual bool setModelData(QWidget* editor, QAbstractItemModel *model, const QModelIndex& index)
{
label.setCheckable(true);
label.setCheckState(Qt::Checked);
return onSetModelData(editor, model, index);
}
virtual bool setEditorData(QWidget */*editor*/, const QModelIndex &/*index*/) const
{
return false;
}
};
class EnumPropertyItem: public PropertyItem
{
public:
EnumPropertyItem(QObject& o, int i):
PropertyItem(o, i)
{
}
virtual void propertyInit() override
{
QMetaEnum e=mp.enumerator();
auto v=mp.read(&obj).toInt();
auto key=e.valueToKey(v);
//value.setData(v);
if (!key)
value.setData(QString("%1 (invalid)").arg(v), Qt::DisplayRole);
else
{
value.setData(key, Qt::DisplayRole);
value.setToolTip(QString("%1 (%2)").arg(key).arg(v));
}
}
virtual QString displayText() const
{
return mp.read(&obj).toString();
}
QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &/*option*/, const QModelIndex &/*index*/) const override
{
QMetaEnum e=mp.enumerator();
auto v=mp.read(&obj).toInt();
auto* cb=new QComboBox(parent);
int selected=0;
for(int i=0; i<e.keyCount(); ++i)
{
//MyDebug()<<"ENUM:"<<i<<e.key(i)<<e.value(i);
cb->addItem(QString("%1 (%2)").arg(e.key(i)).arg(e.value(i)), e.value(i));
if (e.value(i)==v)
selected=i;
}
cb->setCurrentIndex(selected);
return cb;
}
virtual bool onSetModelData(QWidget* editor, QAbstractItemModel */*model*/, const QModelIndex& /*index*/) const override
{
QComboBox* cb=qobject_cast<QComboBox*>(editor);
int v=cb->currentData().toInt();
mp.write(&obj, v);
value.setData(cb->currentText(), Qt::DisplayRole);
MyDebug()<<"property="<<v;
return true;
}
virtual bool setEditorData(QWidget */*editor*/, const QModelIndex &/*index*/) const override
{
return false;
}
};
class MyDelegate: public QStyledItemDelegate
{
QWidget* createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index) const override
{
auto mt_opaque = index.data(MyTypeRole).toULongLong(); //MyTypeRole).toInt();
if (mt_opaque)
{
auto p=reinterpret_cast<PropertyItem*>(mt_opaque);
auto editor=p->createEditor(parent, option, index);
if (editor)
return editor;
}
return QStyledItemDelegate::createEditor(parent, option, index);
}
virtual QString displayText(const QVariant &value, const QLocale &locale) const override
{
return QStyledItemDelegate::displayText(value, locale);
}
virtual void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
auto mt_opaque = index.data(MyTypeRole).toULongLong(); //MyTypeRole).toInt();
if (mt_opaque)
{
auto p=reinterpret_cast<PropertyItem*>(mt_opaque);
if (p->updateEditorGeometry(editor, option, index))
return;
}
QStyledItemDelegate::updateEditorGeometry(editor, option, index);
}
virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
{
QStyledItemDelegate::setModelData(editor, model, index);
auto mt_opaque = index.data(MyTypeRole).toULongLong(); //MyTypeRole).toInt();
if (mt_opaque)
{
auto p=reinterpret_cast<PropertyItem*>(mt_opaque);
if (p->setModelData(editor, model, index))
return;
}
//QStyledItemDelegate::setModelData(editor, model, index);
}
virtual void setEditorData(QWidget *editor, const QModelIndex &index) const override
{
auto mt_opaque = index.data(MyTypeRole).toULongLong(); //MyTypeRole).toInt();
if (mt_opaque)
{
auto p=reinterpret_cast<PropertyItem*>(mt_opaque);
if (p->setEditorData(editor, index))
return;
}
QStyledItemDelegate::setEditorData(editor, index);
}
};
static void populateTreeR(QObject* obj, const QMetaObject* mt, int start, int stop, QStandardItem* root)
{
if (mt==0)
mt=obj->metaObject();
if (start<0)
start=mt->propertyOffset();
if (stop<0)
stop=mt->propertyCount();
for(int i=start; i<stop; ++i)
{
PropertyItem* pi=0;
auto mt=obj->metaObject();
auto mp=mt->property(i);
if (mp.isEnumType() && !mp.isFlagType())
pi=new EnumPropertyItem(*obj, i);
else if (mp.type()==(QVariant::Type)QMetaType::QObjectStar)
{
auto item=new QStandardItem(mp.name());
item->setEditable(false);
//auto i2=new QStandardItem("FAKE");
//item->appendRow(i2);
//i2->setEditable(false);
//QObject* o=((QObject*)mp.read(obj).toULongLong());
QObject* o=reinterpret_cast<QObject*>(mp.read(obj).toLongLong());
if (o)
{
populateTreeR(o, 0, -1, -1, item);
root->appendRow(item);
}
//pi=new PropertyItem(*obj, i);
}
else
pi=new PropertyItem(*obj, i);
pi->propertyInit();
root->appendRow(QList<QStandardItem*>()<<&pi->label<<pi);
}
auto sc=mt->superClass();
if (sc)
{
auto item=new QStandardItem(sc->className());
item->setEditable(false);
//auto i2=new QStandardItem("FAKE");
//item->appendRow(i2);
//i2->setEditable(false);
populateTreeR(obj, sc, sc->propertyOffset(), -1, item);
root->appendRow(item);
}
}
static void populateTree(QObject* obj, QStandardItem* root)
{
populateTreeR(obj, 0, -1, -1, root);
}
QgPropertyWidget::QgPropertyWidget(QObject *obj, QWidget *parent):
QWidget(parent), //QScrollArea(parent),
p_(*new QgPropertyWidget::Implementation)
{
p_.obj=obj;
p_.w=this;
p_.ly=new QVBoxLayout;
p_.lbl=new QLabel(obj->objectName());
p_.ly->addWidget(p_.lbl);
p_.t=new QTreeView(parent);
p_.t->setUniformRowHeights(true);
p_.t->setItemDelegate(new MyDelegate);
p_.m=new QStandardItemModel;
auto root=p_.m->invisibleRootItem();
p_.m->setHeaderData(0, Qt::Horizontal, "Property", Qt::DisplayRole);
p_.m->setHeaderData(1, Qt::Horizontal, "Value", Qt::DisplayRole);
populateTree(obj, root);
connect(p_.t, &QTreeView::expanded,
[=](const QModelIndex&)
{
MyDebug()<<"expanded!";
});
/*
connect(p_.m, &QStandardItemModel::itemChanged,
[=](QStandardItem* item)
{
item->setCheckState(Qt::Checked);
}
);
*/
p_.t->setModel(p_.m);
p_.t->resizeColumnToContents(1);
p_.t->setAlternatingRowColors(true);
p_.ly->addWidget(p_.t);
//p_.bb=new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
//p_.ly->addWidget(p_.bb);
//p_.w->setLayout(p_.ly);
//this->setWidget(p_.w);
setLayout(p_.ly);
//connect(p_.bb, &QDialogButtonBox::accepted, this, QDialog::accept);
//connect(p_.bb, &QDialogButtonBox::rejected, this, QDialog::reject);
}
QgPropertyWidget::~QgPropertyWidget()
{
p_.obj=0;
p_.t->setModel(0);
delete p_.m;
delete &p_;
}
class QgPropertyDialog::Implementation
{
public:
QgPropertyWidget* w;
QVBoxLayout* ly;
QDialogButtonBox* bb;
};
QgPropertyDialog::QgPropertyDialog(QObject* obj, QWidget* parent):
QDialog(parent),
p_(*new QgPropertyDialog::Implementation)
{
p_.w=new QgPropertyWidget(obj, this);
p_.ly=new QVBoxLayout;
p_.ly->addWidget(p_.w);
p_.bb=new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
p_.ly->addWidget(p_.bb);
setLayout(p_.ly);
connect(p_.bb, &QDialogButtonBox::accepted, this, QDialog::accept);
connect(p_.bb, &QDialogButtonBox::rejected, this, QDialog::reject);
}
QgPropertyDialog::~QgPropertyDialog()
{
//setLayout(0);
delete p_.ly;
delete &p_;
}