PIValueTreeEdit develop ...
This commit is contained in:
@@ -1,24 +1,38 @@
|
||||
#include "pivaluetree_edit.h"
|
||||
#include "ui_pivaluetree_edit_array.h"
|
||||
#include "pivariant_edit.h"
|
||||
|
||||
#include "piqt.h"
|
||||
#include "pivariant_edit.h"
|
||||
#include "qinputdialog.h"
|
||||
#include "qmessagebox.h"
|
||||
#include "qtoolbutton.h"
|
||||
#include "ui_pivaluetree_edit_array.h"
|
||||
#include "ui_pivaluetree_edit_parameters.h"
|
||||
|
||||
#include <QEvent>
|
||||
#include <QFormLayout>
|
||||
#include <QGroupBox>
|
||||
|
||||
const char property_name[] = "__name__";
|
||||
|
||||
|
||||
PIValueTreeEdit::PIValueTreeEdit(QWidget * parent): QWidget(parent) {
|
||||
ui = new Ui::PIValueTreeEditArray();
|
||||
grid = new GridWidgets();
|
||||
auto * lay = new QBoxLayout(QBoxLayout::TopToBottom);
|
||||
widget_params = new QDialog();
|
||||
ui_array = new Ui::PIValueTreeEditArray();
|
||||
ui_params = new Ui::PIValueTreeEditParameters();
|
||||
ui_params->setupUi(widget_params);
|
||||
grid = new GridWidgets(ui_params);
|
||||
grid->parent = this;
|
||||
auto * lay = new QBoxLayout(QBoxLayout::TopToBottom);
|
||||
lay->setContentsMargins(0, 0, 0, 0);
|
||||
setLayout(lay);
|
||||
}
|
||||
|
||||
|
||||
PIValueTreeEdit::~PIValueTreeEdit() {
|
||||
delete ui;
|
||||
delete grid;
|
||||
delete ui_params;
|
||||
delete ui_array;
|
||||
delete widget_params;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +54,12 @@ void PIValueTreeEdit::setGroupingEnabled(bool yes) {
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::setFullEditMode(bool yes) {
|
||||
is_full_edit = yes;
|
||||
build();
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::rollback() {
|
||||
build();
|
||||
}
|
||||
@@ -51,14 +71,22 @@ void PIValueTreeEdit::clear() {
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::changeEvent(QEvent * e) {
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
if (widget_array) ui_array->retranslateUi(widget_array);
|
||||
}
|
||||
QWidget::changeEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::removeAll() {
|
||||
array_edits.clear();
|
||||
value_edits.clear();
|
||||
tree_edits.clear();
|
||||
if (ui_array) {
|
||||
ui->layoutArray->takeAt(0);
|
||||
delete ui_array;
|
||||
ui_array = nullptr;
|
||||
if (widget_array) {
|
||||
ui_array->layoutArray->takeAt(0);
|
||||
delete widget_array;
|
||||
widget_array = nullptr;
|
||||
}
|
||||
QLayoutItem * child = nullptr;
|
||||
while ((child = layout()->takeAt(0)) != nullptr) {
|
||||
@@ -70,25 +98,26 @@ void PIValueTreeEdit::removeAll() {
|
||||
|
||||
void PIValueTreeEdit::build() {
|
||||
removeAll();
|
||||
//piCout << source.attributes().value(PIValueTree::attributeArrayType) << array_type;
|
||||
// piCout << source.attributes().value(PIValueTree::attributeArrayType) << array_type;
|
||||
if (source.isArray()) {
|
||||
ui_array = new QWidget();
|
||||
ui->setupUi(ui_array);
|
||||
ui->spinCount->setRange(source.attribute(PIValueTree::attributeArrayMinCount, 0).toInt(),
|
||||
source.attribute(PIValueTree::attributeArrayMaxCount, 65536).toInt());
|
||||
ui->spinCount->setValue(source.children().size_s());
|
||||
ui->widgetEdit->setVisible(source.attribute(PIValueTree::attributeArrayResize, false).toBool());
|
||||
ui->layoutArray->addWidget(grid);
|
||||
grid->create_edit_buttons = false;
|
||||
widget_array = new QWidget();
|
||||
ui_array->setupUi(widget_array);
|
||||
ui_array->spinCount->setRange(source.attribute(PIValueTree::attributeArrayMinCount, 0).toInt(),
|
||||
source.attribute(PIValueTree::attributeArrayMaxCount, 65536).toInt());
|
||||
ui_array->spinCount->setValue(source.children().size_s());
|
||||
ui_array->widgetEdit->setVisible(source.attribute(PIValueTree::attributeArrayResize, false).toBool());
|
||||
ui_array->layoutArray->addWidget(grid);
|
||||
uint array_type = PIVariant::typeIDFromName(source.attribute(PIValueTree::attributeArrayType).toString());
|
||||
int index = 0;
|
||||
int index = 0;
|
||||
for (const auto & i: source.children()) {
|
||||
auto * ve = new PIVariantEdit();
|
||||
ve->setAttributes(source.attributes());
|
||||
ve->setValue(i.value(), array_type);
|
||||
grid->add(QString::number(++index), ve, PI2QString(i.comment()));
|
||||
grid->add(PIValueTree(), QString::number(++index), ve, PI2QString(i.comment()));
|
||||
array_edits << ve;
|
||||
}
|
||||
connect(ui->spinCount, QOverload<int>::of(&QSpinBox::valueChanged), this, [this,array_type](int value){
|
||||
connect(ui_array->spinCount, QOverload<int>::of(&QSpinBox::valueChanged), this, [this, array_type](int value) {
|
||||
value = piMaxi(value, 0);
|
||||
for (int i = grid->rowCount() - 1; i >= value; --i)
|
||||
grid->removeRow(i);
|
||||
@@ -97,12 +126,13 @@ void PIValueTreeEdit::build() {
|
||||
auto * ve = new PIVariantEdit();
|
||||
ve->setAttributes(source.attributes());
|
||||
ve->setValue(PIVariant::fromType(array_type), array_type);
|
||||
grid->add(QString::number(i + 1), ve, "");
|
||||
grid->add(PIValueTree(), QString::number(i + 1), ve, "");
|
||||
array_edits << ve;
|
||||
}
|
||||
});
|
||||
layout()->addWidget(ui_array);
|
||||
layout()->addWidget(widget_array);
|
||||
} else {
|
||||
grid->create_edit_buttons = is_full_edit;
|
||||
layout()->addWidget(grid);
|
||||
for (const auto & i: source.children()) {
|
||||
if (i.attribute(PIValueTree::attributeHidden, false).toBool()) continue;
|
||||
@@ -110,12 +140,16 @@ void PIValueTreeEdit::build() {
|
||||
if (i.name().isEmpty()) continue;
|
||||
auto * l = new QLabel(PI2QString(i.name()));
|
||||
l->setAlignment(Qt::AlignCenter);
|
||||
grid->add(l);
|
||||
grid->add(i, l);
|
||||
continue;
|
||||
}
|
||||
if (i.hasChildren() || i.isArray()) {
|
||||
auto * ve = new PIValueTreeEdit();
|
||||
auto * ve = new PIValueTreeEdit();
|
||||
PIStringList rp = root_path;
|
||||
rp << i.name();
|
||||
ve->root_path = rp;
|
||||
ve->setGroupingEnabled(is_grouping);
|
||||
ve->setFullEditMode(is_full_edit);
|
||||
ve->setValue(i);
|
||||
if (is_grouping) {
|
||||
auto * gb = new QGroupBox();
|
||||
@@ -127,16 +161,16 @@ void PIValueTreeEdit::build() {
|
||||
gb->setChecked(true);
|
||||
gb->setAlignment(Qt::AlignCenter);
|
||||
connect(gb, &QGroupBox::toggled, ve, &QWidget::setVisible);
|
||||
grid->add(gb);
|
||||
grid->add(i, gb);
|
||||
} else {
|
||||
grid->add(PI2QString(i.name()), ve, PI2QString(i.comment()));
|
||||
grid->add(i, PI2QString(i.name()), ve, PI2QString(i.comment()));
|
||||
}
|
||||
tree_edits[i.name()] = ve;
|
||||
} else {
|
||||
auto * ve = new PIVariantEdit();
|
||||
ve->setAttributes(i.attributes());
|
||||
ve->setValue(i.value());
|
||||
grid->add(PI2QString(i.name()), ve, PI2QString(i.comment()));
|
||||
grid->add(i, PI2QString(i.name()), ve, PI2QString(i.comment()));
|
||||
value_edits[i.name()] = ve;
|
||||
}
|
||||
}
|
||||
@@ -146,8 +180,7 @@ void PIValueTreeEdit::build() {
|
||||
|
||||
void PIValueTreeEdit::applyValues() const {
|
||||
if (source.isArray()) {
|
||||
if (array_edits.isNotEmpty())
|
||||
source.mergeAttributes(array_edits[0]->defaultAttributes());
|
||||
if (array_edits.isNotEmpty()) source.mergeAttributes(array_edits[0]->defaultAttributes());
|
||||
source.clearChildren();
|
||||
for (int i = 0; i < array_edits.size_s(); ++i)
|
||||
source.addChild({PIString::fromNumber(i), array_edits[i]->value()});
|
||||
@@ -167,35 +200,139 @@ void PIValueTreeEdit::applyValues() const {
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::actionTriggered(QToolButton * button, const PIString & vn, QAction * a) {
|
||||
if (a == ui_params->actionRename) {
|
||||
PIString nn = Q2PIString(QInputDialog::getText(nullptr, tr("Rename"), tr("Input new name:"), QLineEdit::Normal, PI2QString(vn)));
|
||||
if (nn.isEmpty() || (nn == vn)) return;
|
||||
for (const auto & c: source.children()) {
|
||||
if (c.name() == nn) {
|
||||
QMessageBox::critical(nullptr, tr("Rename"), tr("This name already exists!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
source[vn].setName(nn);
|
||||
button->setProperty(property_name, PI2QString(nn));
|
||||
grid->rename(PI2QString(vn), PI2QString(nn));
|
||||
}
|
||||
if (a == ui_params->actionRemove) {
|
||||
source.remove(vn);
|
||||
grid->removeRow(grid->getRow(button));
|
||||
}
|
||||
if (a == ui_params->actionChange) {
|
||||
if (last_IDs_count != PIVariant::knownTypeIDsCount()) {
|
||||
last_IDs_count = PIVariant::knownTypeIDsCount();
|
||||
ui_params->comboType->clear();
|
||||
auto ids = PIVariant::knownTypeIDs();
|
||||
PIVector<PIPair<uint, QString>> types;
|
||||
for (auto id: ids) {
|
||||
if (!PIVariantEditorBase::editorExists(id)) continue;
|
||||
PIString tn = PIVariant::typeNameFromID(id);
|
||||
if (tn.startsWith("PI")) tn.remove(0, 2);
|
||||
if (tn.startsWith("VariantTypes::")) tn.remove(0, 14);
|
||||
types.append({id, PI2QString(tn)});
|
||||
}
|
||||
types.sort([](const PIPair<uint, QString> & a, const PIPair<uint, QString> & b) {
|
||||
return QString::localeAwareCompare(a.second, b.second) < 0;
|
||||
});
|
||||
for (const auto & t: types)
|
||||
ui_params->comboType->addItem(t.second, t.first);
|
||||
}
|
||||
auto old_vt = source.child(vn);
|
||||
ui_params->comboType->setCurrentIndex(ui_params->comboType->findData(old_vt.value().typeID()));
|
||||
ui_params->checkArray->setChecked(old_vt.isArray());
|
||||
if (widget_params->exec() != QDialog::Accepted) return;
|
||||
auto & el(source[vn]);
|
||||
uint nid = ui_params->comboType->currentData().toUInt();
|
||||
PIString vs = el.value().toString();
|
||||
PIVariant var = PIVariant::fromType(nid);
|
||||
var.setValueFromString(vs);
|
||||
source[vn].setValue(var);
|
||||
build();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::GridWidgets::add(QString label, QWidget * w, const QString & comment) {
|
||||
if (!label.isEmpty())
|
||||
label += ':';
|
||||
// PIValueTreeEdit::GridWidgets
|
||||
|
||||
PIValueTreeEdit::GridWidgets::GridWidgets(Ui::PIValueTreeEditParameters * ui_) {
|
||||
ui_params = ui_;
|
||||
icon_conf = QIcon(":/icons/configure.png");
|
||||
conf_menu.addActions({ui_params->actionRename, ui_params->actionChange, ui_params->actionRemove});
|
||||
}
|
||||
|
||||
|
||||
int PIValueTreeEdit::GridWidgets::getRow(QWidget * w) const {
|
||||
if (!w) return -1;
|
||||
for (int r = 0; r < lay->rowCount(); ++r) {
|
||||
for (int c = 0; c < lay->columnCount(); ++c) {
|
||||
auto * li = lay->itemAtPosition(r, c);
|
||||
if (li) {
|
||||
if (li->widget()) {
|
||||
if (li->widget() == w) return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::GridWidgets::add(const PIValueTree & vt, QString label, QWidget * w, const QString & comment) {
|
||||
int col = beginRow(vt);
|
||||
if (!label.isEmpty()) label += ':';
|
||||
auto * l = new QLabel(label);
|
||||
auto * c = new QLabel(comment);
|
||||
l->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
c->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
w->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
lay->addWidget(l, row_count, 0, Qt::AlignVCenter | Qt::AlignRight);
|
||||
lay->addWidget(w, row_count, 1);
|
||||
lay->addWidget(c, row_count, 2, Qt::AlignVCenter | Qt::AlignLeft);
|
||||
lay->addWidget(l, row_count, col++, Qt::AlignVCenter | Qt::AlignRight);
|
||||
lay->addWidget(w, row_count, col++);
|
||||
lay->addWidget(c, row_count, col++, Qt::AlignVCenter | Qt::AlignLeft);
|
||||
widgets << l << w << c;
|
||||
labels << l;
|
||||
++row_count;
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::GridWidgets::add(QWidget * w) {
|
||||
lay->addWidget(w, row_count, 0, 1, -1);
|
||||
void PIValueTreeEdit::GridWidgets::add(const PIValueTree & vt, QWidget * w) {
|
||||
int col = beginRow(vt);
|
||||
lay->addWidget(w, row_count, col, 1, -1);
|
||||
widgets << w;
|
||||
++row_count;
|
||||
}
|
||||
|
||||
|
||||
int PIValueTreeEdit::GridWidgets::beginRow(const PIValueTree & vt) {
|
||||
if (!create_edit_buttons) return 0;
|
||||
auto * b = new QToolButton();
|
||||
b->setIcon(icon_conf);
|
||||
b->setPopupMode(QToolButton::InstantPopup);
|
||||
b->setMenu(&conf_menu);
|
||||
b->setProperty(property_name, PI2QString(vt.name()));
|
||||
lay->addWidget(b, row_count, 0);
|
||||
connect(b, &QToolButton::triggered, this, [this, b](QAction * a) {
|
||||
parent->actionTriggered(b, Q2PIString(b->property(property_name).toString()), a);
|
||||
});
|
||||
widgets << b;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::GridWidgets::rename(QString prev_name, QString new_name) {
|
||||
if (!prev_name.isEmpty()) prev_name += ':';
|
||||
if (!new_name.isEmpty()) new_name += ':';
|
||||
for (auto * l: labels)
|
||||
if (l->text() == prev_name) {
|
||||
l->setText(new_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::GridWidgets::clear() {
|
||||
piDeleteAllAndClear(widgets);
|
||||
if (lay)
|
||||
delete lay;
|
||||
labels.clear();
|
||||
if (lay) delete lay;
|
||||
lay = new QGridLayout();
|
||||
lay->setContentsMargins(0, 0, 0, 0);
|
||||
setLayout(lay);
|
||||
@@ -204,13 +341,14 @@ void PIValueTreeEdit::GridWidgets::clear() {
|
||||
|
||||
|
||||
void PIValueTreeEdit::GridWidgets::removeRow(int index) {
|
||||
if (!lay) return;
|
||||
if (row_count <= index) return;
|
||||
if (!lay || index < 0 || row_count <= index) return;
|
||||
for (int c = 0; c < lay->columnCount(); ++c) {
|
||||
auto * li = lay->itemAtPosition(index, c);
|
||||
if (li) {
|
||||
if (li->widget()) {
|
||||
widgets.removeOne(li->widget());
|
||||
QLabel * lbl = qobject_cast<QLabel *>(li->widget());
|
||||
if (lbl) labels.removeOne(lbl);
|
||||
delete li->widget();
|
||||
}
|
||||
delete li;
|
||||
@@ -223,27 +361,26 @@ void PIValueTreeEdit::GridWidgets::removeRow(int index) {
|
||||
|
||||
void PIValueTreeEdit::GridWidgets::simplify() {
|
||||
if (!lay) return;
|
||||
QVector<QMap<int, QWidget*>> wg;
|
||||
QMap<QWidget*, Qt::Alignment> wa;
|
||||
QVector<QMap<int, QWidget *>> wg;
|
||||
QMap<QWidget *, Qt::Alignment> wa;
|
||||
for (int r = 0; r < lay->rowCount(); ++r) {
|
||||
QMap<int, QWidget*> row;
|
||||
QMap<int, QWidget *> row;
|
||||
for (int c = 0; c < lay->columnCount(); ++c) {
|
||||
auto * li = lay->itemAtPosition(r, c);
|
||||
if (!li) continue;
|
||||
if (li->widget()) {
|
||||
row[c] = li->widget();
|
||||
row[c] = li->widget();
|
||||
wa[li->widget()] = li->alignment();
|
||||
}
|
||||
}
|
||||
if (!row.isEmpty())
|
||||
wg << row;
|
||||
if (!row.isEmpty()) wg << row;
|
||||
}
|
||||
delete lay;
|
||||
lay = new QGridLayout();
|
||||
lay->setContentsMargins(0, 0, 0, 0);
|
||||
int rindex = 0;
|
||||
for (const auto & row: wg) {
|
||||
QMapIterator<int, QWidget*> it(row);
|
||||
QMapIterator<int, QWidget *> it(row);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
lay->addWidget(it.value(), rindex, it.key(), wa.value(it.value()));
|
||||
|
||||
Reference in New Issue
Block a user