rename libs/piqt_widgtes to libs/piqt_utils
add PIVariantEdit for PIGeoPosition
This commit is contained in:
769
libs/piqt_utils/pivaluetree_edit.cpp
Normal file
769
libs/piqt_utils/pivaluetree_edit.cpp
Normal file
@@ -0,0 +1,769 @@
|
||||
#include "pivaluetree_edit.h"
|
||||
|
||||
#include "piqt.h"
|
||||
#include "pivaluetree_edit_parameters.h"
|
||||
#include "pivaluetree_edit_reorder.h"
|
||||
#include "pivariant_edit.h"
|
||||
#include "ui_pivaluetree_edit_array.h"
|
||||
|
||||
#include <QEvent>
|
||||
#include <QFormLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QInputDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QTabWidget>
|
||||
#include <QToolButton>
|
||||
|
||||
using Attribute = PIValueTree::Attribute;
|
||||
|
||||
const char property_name[] = "__name__";
|
||||
|
||||
|
||||
class GroupBox: public QGroupBox {
|
||||
public:
|
||||
GroupBox(QWidget * content = nullptr): QGroupBox() {
|
||||
icon_show = QIcon(":/icons/layer-visible-on.png");
|
||||
icon_hide = QIcon(":/icons/layer-visible-off.png");
|
||||
setLayout(new QBoxLayout(QBoxLayout::TopToBottom));
|
||||
layout()->addWidget(content);
|
||||
setAlignment(Qt::AlignCenter);
|
||||
btn = new QToolButton(this);
|
||||
btn->setCheckable(true);
|
||||
btn->show();
|
||||
connect(btn, &QToolButton::toggled, this, [this, content](bool on) {
|
||||
btn->setIcon(on ? icon_show : icon_hide);
|
||||
content->setVisible(on);
|
||||
});
|
||||
btn->setChecked(true);
|
||||
}
|
||||
|
||||
private:
|
||||
void resizeEvent(QResizeEvent * e) {
|
||||
QGroupBox::resizeEvent(e);
|
||||
btn->resize(btn->height(), btn->height());
|
||||
btn->move(btn->height() / 2, 0);
|
||||
}
|
||||
QToolButton * btn = nullptr;
|
||||
QIcon icon_show, icon_hide;
|
||||
};
|
||||
|
||||
|
||||
PIValueTreeEdit::PIValueTreeEdit(QWidget * parent): QWidget(parent) {
|
||||
widget_params = new PIValueTreeEditParameters();
|
||||
widget_reorder = new PIValueTreeEditReorder();
|
||||
ui_array = new Ui::PIValueTreeEditArray();
|
||||
grid = new GridWidgets(this);
|
||||
auto * lay = new QBoxLayout(QBoxLayout::TopToBottom);
|
||||
lay->setContentsMargins(0, 0, 0, 0);
|
||||
setLayout(lay);
|
||||
}
|
||||
|
||||
|
||||
PIValueTreeEdit::~PIValueTreeEdit() {
|
||||
delete grid;
|
||||
delete ui_array;
|
||||
delete widget_params;
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::setValue(const PIValueTree & v) {
|
||||
current = source = v;
|
||||
build();
|
||||
}
|
||||
|
||||
|
||||
PIValueTree PIValueTreeEdit::value() const {
|
||||
applyValues();
|
||||
return current;
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::setGrouping(Grouping g) {
|
||||
applyValues();
|
||||
cur_grouping = real_grouping = g;
|
||||
if (parent_tree && g == Parent) real_grouping = parent_tree->real_grouping;
|
||||
if (real_grouping == Parent) real_grouping = Indent;
|
||||
for (auto * a: widget_params->menu_grouping.actions()) {
|
||||
if (a->data().toInt() == g) {
|
||||
a->setChecked(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
build();
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::setFullEditMode(bool yes) {
|
||||
applyValues();
|
||||
is_full_edit = yes;
|
||||
build();
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::rollback() {
|
||||
current = source;
|
||||
build();
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::clear() {
|
||||
current = PIValueTree();
|
||||
removeAll();
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::retranslate() {
|
||||
for (const auto & i: value_edits)
|
||||
i.second->retranslate();
|
||||
for (const auto & i: tree_edits)
|
||||
i.second->retranslate();
|
||||
for (const auto & i: comm_labels) {
|
||||
i.second->setText(PIVariantEditorBase::vtTr(current.child(i.first).comment()));
|
||||
}
|
||||
for (const auto & i: label_labels) {
|
||||
i.second->setText(PIVariantEditorBase::vtTr(i.first));
|
||||
}
|
||||
if (tab_widget) {
|
||||
for (int i = 0; i < tab_widget->count(); ++i) {
|
||||
tab_widget->setTabText(i, PIVariantEditorBase::vtTr(Q2PIString(tab_widget->tabBar()->tabData(i).toString())));
|
||||
}
|
||||
}
|
||||
grid->retranslate();
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::changeEvent(QEvent * e) {
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
if (widget_array) ui_array->retranslateUi(widget_array);
|
||||
retranslate();
|
||||
}
|
||||
QWidget::changeEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::removeAll() {
|
||||
array_edits.clear();
|
||||
value_edits.clear();
|
||||
tree_edits.clear();
|
||||
comm_labels.clear();
|
||||
label_labels.clear();
|
||||
tab_widget = nullptr;
|
||||
if (widget_array) {
|
||||
ui_array->layoutArray->removeWidget(grid);
|
||||
grid->hide();
|
||||
grid->setParent(this);
|
||||
delete widget_array;
|
||||
widget_array = nullptr;
|
||||
}
|
||||
QLayoutItem * child = nullptr;
|
||||
while ((child = layout()->takeAt(0))) {
|
||||
delete child;
|
||||
}
|
||||
grid->clear();
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::build() {
|
||||
grid->create_edit_buttons = false;
|
||||
removeAll();
|
||||
// piCout << source.attributes().value(Attribute::arrayType) << array_type;
|
||||
grid->button_add->hide();
|
||||
if (current.isArray()) {
|
||||
widget_array = new QWidget();
|
||||
ui_array->setupUi(widget_array);
|
||||
applyArrayAttributes();
|
||||
ui_array->layoutArray->addWidget(grid);
|
||||
grid->show();
|
||||
uint array_type = PIVariant::typeIDFromName(current.attribute(Attribute::arrayType).toString());
|
||||
int index = 0;
|
||||
for (const auto & i: current.children()) {
|
||||
auto * ve = new PIVariantEdit();
|
||||
ve->setAttributes(current.attributes());
|
||||
ve->setValue(i.value(), array_type);
|
||||
grid->add(PIValueTree(), PIString::fromNumber(++index), ve, i.comment());
|
||||
array_edits << ve;
|
||||
}
|
||||
connect(ui_array->spinCount, QOverload<int>::of(&QSpinBox::valueChanged), widget_array, [this, array_type](int value) {
|
||||
value = piMaxi(value, 0);
|
||||
for (int i = grid->rowCount() - 1; i >= value; --i)
|
||||
grid->removeRow(i);
|
||||
array_edits.resize(grid->rowCount());
|
||||
for (int i = grid->rowCount(); i < value; ++i) {
|
||||
auto * ve = new PIVariantEdit();
|
||||
ve->setAttributes(current.attributes());
|
||||
ve->setValue(PIVariant::fromType(array_type), array_type);
|
||||
grid->add(PIValueTree(), PIString::fromNumber(i + 1), ve, "");
|
||||
array_edits << ve;
|
||||
}
|
||||
});
|
||||
layout()->addWidget(widget_array);
|
||||
} else {
|
||||
grid->create_edit_buttons = is_full_edit;
|
||||
layout()->addWidget(grid);
|
||||
if (!current.hasChildren()) grid->clear();
|
||||
for (const auto & i: current.children()) {
|
||||
if (i.attribute(Attribute::hidden, false).toBool() && !is_full_edit) continue;
|
||||
if (i.attribute(Attribute::isLabel, false).toBool()) {
|
||||
if (i.name().isEmpty()) continue;
|
||||
auto * l = newLabel(i);
|
||||
grid->add(i, l);
|
||||
continue;
|
||||
}
|
||||
if (i.hasChildren() || i.isArray()) {
|
||||
addTreeEdit(i);
|
||||
} else {
|
||||
addValueEdit(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::applyValues() const {
|
||||
if (current.isArray()) {
|
||||
if (array_edits.isNotEmpty()) current.mergeAttributes(array_edits[0]->attributes());
|
||||
current.clearChildren();
|
||||
for (int i = 0; i < array_edits.size_s(); ++i)
|
||||
current.addChild({PIString::fromNumber(i), array_edits[i]->value()});
|
||||
} else {
|
||||
auto vit = value_edits.makeIterator();
|
||||
while (vit.next()) {
|
||||
auto & c(current.child(vit.key()));
|
||||
c.mergeAttributes(vit.value()->attributes());
|
||||
c.setValue(vit.value()->value());
|
||||
}
|
||||
auto tit = tree_edits.makeIterator();
|
||||
while (tit.next()) {
|
||||
auto & c(current.child(tit.key()));
|
||||
if (!c.isNull()) c = tit.value()->value();
|
||||
}
|
||||
if (current.hasChildren()) {
|
||||
auto ge = PIVariantEditorBase::createGrouping();
|
||||
ge.selectValue(cur_grouping);
|
||||
current.setAttribute(Attribute::grouping, ge);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::actionTriggered(QToolButton * button, const PIString & vn, QAction * a) {
|
||||
if (a == widget_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: current.children()) {
|
||||
if (c.name() == nn) {
|
||||
QMessageBox::critical(nullptr, tr("Rename"), tr("This name already exists!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
current[vn].setName(nn);
|
||||
button->setProperty(property_name, PI2QString(nn));
|
||||
grid->rename(vn, nn);
|
||||
if (value_edits.contains(vn)) {
|
||||
value_edits[nn] = value_edits[vn];
|
||||
value_edits.remove(vn);
|
||||
}
|
||||
if (tree_edits.contains(vn)) {
|
||||
tree_edits[nn] = tree_edits[vn];
|
||||
tree_edits.remove(vn);
|
||||
}
|
||||
if (comm_labels.contains(vn)) {
|
||||
comm_labels[nn] = comm_labels[vn];
|
||||
comm_labels.remove(vn);
|
||||
}
|
||||
if (label_labels.contains(vn)) {
|
||||
label_labels[nn] = label_labels[vn];
|
||||
label_labels[nn]->setText(PIVariantEditorBase::vtTr(nn));
|
||||
label_labels.remove(vn);
|
||||
}
|
||||
if (tab_widget) {
|
||||
for (int i = 0; i < tab_widget->count(); ++i) {
|
||||
if (tab_widget->tabBar()->tabData(i).toString() == PI2QString(vn)) {
|
||||
tab_widget->setTabText(i, PIVariantEditorBase::vtTr(nn));
|
||||
tab_widget->tabBar()->setTabData(i, PI2QString(nn));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (a == widget_params->actionRemove) {
|
||||
current.remove(vn);
|
||||
if (tab_widget) {
|
||||
QString qvn = PI2QString(vn);
|
||||
QMetaObject::invokeMethod(
|
||||
this,
|
||||
[this, qvn]() {
|
||||
for (int i = 0; i < tab_widget->count(); ++i) {
|
||||
if (tab_widget->tabBar()->tabData(i).toString() == qvn) {
|
||||
tab_widget->removeTab(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tab_widget->count() == 0) {
|
||||
grid->removeRow(grid->getRow(tab_widget));
|
||||
tab_widget = nullptr;
|
||||
}
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
grid->removeRow(grid->getRow(button));
|
||||
value_edits.remove(vn);
|
||||
tree_edits.remove(vn);
|
||||
comm_labels.remove(vn);
|
||||
label_labels.remove(vn);
|
||||
return;
|
||||
}
|
||||
if (a == widget_params->actionChange) {
|
||||
auto & vt(current[vn]);
|
||||
if (vt.isArray()) {
|
||||
auto * ve = tree_edits.value(vn, nullptr);
|
||||
if (!ve) return;
|
||||
vt = ve->value();
|
||||
if (!widget_params->showFor(vt)) return;
|
||||
ve->setValue(vt);
|
||||
// ve->applyArrayAttributes();
|
||||
} else {
|
||||
bool was_label = vt.attribute(Attribute::isLabel, false).toBool();
|
||||
auto * ve = value_edits.value(vn, nullptr);
|
||||
if (ve) {
|
||||
vt.setValue(ve->value());
|
||||
vt.mergeAttributes(ve->attributes());
|
||||
}
|
||||
if (!widget_params->showFor(vt)) return;
|
||||
bool now_label = vt.attribute(Attribute::isLabel, false).toBool();
|
||||
if (was_label ^ now_label) {
|
||||
if (now_label) {
|
||||
auto * l = newLabel(vt);
|
||||
grid->replace(grid->getRow(button), l);
|
||||
value_edits.remove(vt.name());
|
||||
comm_labels.remove(vt.name());
|
||||
} else {
|
||||
auto * ve = new PIVariantEdit();
|
||||
applyVariantEdit(ve, vt);
|
||||
grid->replace(grid->getRow(button), vt.name(), ve, vt.comment());
|
||||
value_edits[vt.name()] = ve;
|
||||
}
|
||||
ve = nullptr;
|
||||
}
|
||||
if (ve) {
|
||||
applyVariantEdit(ve, vt);
|
||||
}
|
||||
if (now_label) {
|
||||
label_labels[vt.name()]->setStyleSheet(PI2QString(vt.attribute(Attribute::style).toString()));
|
||||
}
|
||||
}
|
||||
auto * cl = comm_labels.value(vn, nullptr);
|
||||
if (cl) cl->setText(PIVariantEditorBase::vtTr(vt.comment()));
|
||||
return;
|
||||
}
|
||||
if (a == widget_params->actionReorder) {
|
||||
if (!widget_reorder->showFor(current)) return;
|
||||
grid->reorder(widget_reorder->map);
|
||||
auto cl = current.children();
|
||||
current.clearChildren();
|
||||
for (int i = 0; i < cl.size_s(); ++i) {
|
||||
int mi = widget_reorder->map.value(i, i);
|
||||
if (mi < 0 || mi >= cl.size_s()) continue;
|
||||
current.addChild(cl[mi]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
setGrouping((Grouping)a->data().toInt());
|
||||
}
|
||||
|
||||
|
||||
PIValueTreeEdit * PIValueTreeEdit::addTreeEdit(const PIValueTree & vt) {
|
||||
auto * ve = new PIValueTreeEdit();
|
||||
PIStringList rp = root_path;
|
||||
rp << vt.name();
|
||||
ve->root_path = rp;
|
||||
ve->parent_tree = this;
|
||||
ve->setGrouping((Grouping)vt.attribute(Attribute::grouping, Parent).toEnum().selectedValue());
|
||||
ve->setFullEditMode(is_full_edit);
|
||||
ve->setValue(vt);
|
||||
switch (real_grouping) {
|
||||
case Indent: grid->add(vt, vt.name(), ve, vt.comment(), true); break;
|
||||
case Groups: {
|
||||
auto * gb = new GroupBox(ve);
|
||||
gb->setTitle(PI2QString(vt.name()));
|
||||
gb->setToolTip(PI2QString(vt.comment()));
|
||||
gb->setProperty(property_name, PI2QString(vt.name()));
|
||||
grid->add(vt, gb, true);
|
||||
} break;
|
||||
case Tabs: {
|
||||
createTabWidget();
|
||||
auto * cw = new QWidget();
|
||||
cw->setLayout(new QBoxLayout(QBoxLayout::TopToBottom));
|
||||
cw->layout()->addWidget(ve);
|
||||
cw->layout()->addItem(new QSpacerItem(0, 0, QSizePolicy::Preferred, QSizePolicy::Expanding));
|
||||
int tab = tab_widget->addTab(cw, PIVariantEditorBase::vtTr(vt.name()));
|
||||
tab_widget->tabBar()->setTabData(tab, PI2QString(vt.name()));
|
||||
if (is_full_edit) {
|
||||
auto * b = grid->createConfigButton(vt, true);
|
||||
tab_widget->tabBar()->setTabButton(tab, QTabBar::RightSide, b);
|
||||
}
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
tree_edits[vt.name()] = ve;
|
||||
return ve;
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::addValueEdit(const PIValueTree & vt) {
|
||||
auto * ve = new PIVariantEdit();
|
||||
applyVariantEdit(ve, vt);
|
||||
grid->add(vt, vt.name(), ve, vt.comment());
|
||||
value_edits[vt.name()] = ve;
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::applyArrayAttributes() {
|
||||
ui_array->spinCount->setRange(current.attribute(Attribute::arrayMinCount, 0).toInt(),
|
||||
current.attribute(Attribute::arrayMaxCount, 65536).toInt());
|
||||
ui_array->spinCount->setValue(current.children().size_s());
|
||||
ui_array->widgetEdit->setVisible(current.attribute(Attribute::arrayResize, false).toBool());
|
||||
uint array_type = PIVariant::typeIDFromName(current.attribute(Attribute::arrayType).toString());
|
||||
for (int i = 0; i < array_edits.size_s(); ++i) {
|
||||
auto * w = array_edits[i];
|
||||
w->setAttributes(current.attributes());
|
||||
w->setValue(i < current.children().size_s() ? current.children()[i].value() : PIVariant(), array_type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QLabel * PIValueTreeEdit::newLabel(const PIValueTree & vt) {
|
||||
auto * l = new QLabel();
|
||||
l->setAlignment(Qt::AlignCenter);
|
||||
l->setText(PIVariantEditorBase::vtTr(vt.name()));
|
||||
l->setStyleSheet(PI2QString(vt.attribute(Attribute::style).toString()));
|
||||
label_labels[vt.name()] = l;
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::applyVariantEdit(PIVariantEdit * ve, const PIValueTree & vt) {
|
||||
ve->setAttributes(vt.attributes());
|
||||
ve->setValue(vt.value());
|
||||
ve->setFullEditMode(is_full_edit);
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::createTabWidget() {
|
||||
if (tab_widget) return;
|
||||
tab_widget = new QTabWidget();
|
||||
grid->addRow(tab_widget);
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::newRequest(NewType type) {
|
||||
PIString nn = Q2PIString(QInputDialog::getText(nullptr, tr("New item"), tr("Input new name:")));
|
||||
if (nn.isEmpty()) return;
|
||||
for (const auto & c: current.children()) {
|
||||
if (c.name() == nn) {
|
||||
QMessageBox::critical(nullptr, tr("New item"), tr("This name already exists!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
PIValueTree vt;
|
||||
vt.setName(nn);
|
||||
if (type == NewType::Value) {
|
||||
if (!widget_params->showFor(vt)) return;
|
||||
}
|
||||
if (type == NewType::Array) {
|
||||
vt.setAttribute(Attribute::arrayType, PIVariant::typeName<PIString>());
|
||||
if (!widget_params->showFor(vt)) return;
|
||||
}
|
||||
current.addChild(vt);
|
||||
switch (type) {
|
||||
case NewType::Value: addValueEdit(vt); break;
|
||||
case NewType::Group: addTreeEdit(vt); break;
|
||||
case NewType::Array: addTreeEdit(vt); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// PIValueTreeEdit::GridWidgets
|
||||
|
||||
PIValueTreeEdit::GridWidgets::GridWidgets(PIValueTreeEdit * p) {
|
||||
parent = p;
|
||||
icon_conf = QIcon(":/icons/configure.png");
|
||||
auto newSeparator = []() {
|
||||
auto * a = new QAction();
|
||||
a->setSeparator(true);
|
||||
return a;
|
||||
};
|
||||
menu_group.addActions({p->widget_params->actionRename,
|
||||
p->widget_params->actionReorder,
|
||||
p->widget_params->menu_grouping.menuAction(),
|
||||
newSeparator(),
|
||||
p->widget_params->actionRemove});
|
||||
menu_conf.addActions({p->widget_params->actionRename,
|
||||
p->widget_params->actionChange,
|
||||
p->widget_params->actionReorder,
|
||||
newSeparator(),
|
||||
p->widget_params->actionRemove});
|
||||
menu_new.addActions({p->widget_params->actionValue, p->widget_params->actionGroup, p->widget_params->actionArray});
|
||||
button_add = new QToolButton();
|
||||
button_add->setIcon(QIcon(":/icons/list-add.png"));
|
||||
button_add->setPopupMode(QToolButton::InstantPopup);
|
||||
button_add->setMenu(&menu_new);
|
||||
p->widget_params->actionValue->setData((int)NewType::Value);
|
||||
p->widget_params->actionGroup->setData((int)NewType::Group);
|
||||
p->widget_params->actionArray->setData((int)NewType::Array);
|
||||
connect(button_add, &QToolButton::triggered, this, [this](QAction * a) { parent->newRequest((NewType)a->data().toInt()); });
|
||||
}
|
||||
|
||||
|
||||
PIValueTreeEdit::GridWidgets::~GridWidgets() {
|
||||
delete button_add;
|
||||
}
|
||||
|
||||
|
||||
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) continue;
|
||||
if (li->widget() && (li->widget() == w)) return r;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::GridWidgets::add(const PIValueTree & vt,
|
||||
const PIString & label,
|
||||
QWidget * w,
|
||||
const PIString & comment,
|
||||
bool is_group) {
|
||||
int col = beginRow(vt, is_group);
|
||||
auto * l = new QLabel();
|
||||
auto * c = new QLabel(PIVariantEditorBase::vtTr(comment));
|
||||
l->setProperty(property_name, PI2QString(label));
|
||||
QString nn = PIVariantEditorBase::vtTr(label);
|
||||
if (!nn.isEmpty()) nn += ':';
|
||||
l->setText(nn);
|
||||
l->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
c->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
w->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
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;
|
||||
parent->comm_labels[vt.name()] = c;
|
||||
++row_count;
|
||||
changed();
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::GridWidgets::add(const PIValueTree & vt, QWidget * w, bool is_group) {
|
||||
int col = beginRow(vt, is_group);
|
||||
lay->addWidget(w, row_count, col, 1, -1);
|
||||
widgets << w;
|
||||
++row_count;
|
||||
changed();
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::GridWidgets::addRow(QWidget * w) {
|
||||
lay->addWidget(w, row_count, 0, 1, -1);
|
||||
widgets << w;
|
||||
++row_count;
|
||||
changed();
|
||||
}
|
||||
|
||||
|
||||
QToolButton * PIValueTreeEdit::GridWidgets::createConfigButton(const PIValueTree & vt, bool is_group) {
|
||||
auto * b = new QToolButton();
|
||||
b->setIcon(icon_conf);
|
||||
b->setPopupMode(QToolButton::InstantPopup);
|
||||
b->setMenu((is_group && !vt.isArray()) ? &menu_group : &menu_conf);
|
||||
b->setProperty(property_name, PI2QString(vt.name()));
|
||||
b->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
connect(b, &QToolButton::triggered, this, [this, b](QAction * a) {
|
||||
parent->actionTriggered(b, Q2PIString(b->property(property_name).toString()), a);
|
||||
});
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::GridWidgets::replace(int row, QWidget * w) {
|
||||
int col = removeRowEdits(row);
|
||||
lay->addWidget(w, row, col, 1, -1);
|
||||
widgets << w;
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::GridWidgets::replace(int row, const PIString & label, QWidget * w, const PIString & comment) {
|
||||
int col = removeRowEdits(row);
|
||||
auto * l = new QLabel();
|
||||
auto * c = new QLabel(PIVariantEditorBase::vtTr(comment));
|
||||
l->setProperty(property_name, PI2QString(label));
|
||||
QString nn = PIVariantEditorBase::vtTr(label);
|
||||
if (!nn.isEmpty()) nn += ':';
|
||||
l->setText(nn);
|
||||
l->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
c->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
w->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
lay->addWidget(l, row, col++, Qt::AlignVCenter | Qt::AlignRight);
|
||||
lay->addWidget(w, row, col++);
|
||||
lay->addWidget(c, row, col++, Qt::AlignVCenter | Qt::AlignLeft);
|
||||
widgets << l << w << c;
|
||||
labels << l;
|
||||
parent->comm_labels[label] = c;
|
||||
}
|
||||
|
||||
|
||||
int PIValueTreeEdit::GridWidgets::beginRow(const PIValueTree & vt, bool is_group) {
|
||||
if (!create_edit_buttons) return 0;
|
||||
auto * b = createConfigButton(vt, is_group);
|
||||
lay->addWidget(b, row_count, 0);
|
||||
widgets << b;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::GridWidgets::rename(const PIString & prev_name, const PIString & new_name) {
|
||||
for (auto * w: widgets) {
|
||||
auto * gb = qobject_cast<QGroupBox *>(w);
|
||||
if (!gb) continue;
|
||||
if (gb->property(property_name).toString() == PI2QString(prev_name)) {
|
||||
gb->setProperty(property_name, PI2QString(new_name));
|
||||
gb->setTitle(PIVariantEditorBase::vtTr(new_name));
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (auto * l: labels)
|
||||
if (l->property(property_name).toString() == PI2QString(prev_name)) {
|
||||
l->setProperty(property_name, PI2QString(new_name));
|
||||
QString nn = PIVariantEditorBase::vtTr(new_name);
|
||||
if (!nn.isEmpty()) nn += ':';
|
||||
l->setText(nn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::GridWidgets::clear() {
|
||||
piDeleteAllAndClear(widgets);
|
||||
labels.clear();
|
||||
if (lay) delete lay;
|
||||
lay = new QGridLayout();
|
||||
lay->setContentsMargins(0, 0, 0, 0);
|
||||
setLayout(lay);
|
||||
row_count = 0;
|
||||
changed();
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::GridWidgets::changed() {
|
||||
if (!create_edit_buttons || !lay) return;
|
||||
lay->addWidget(button_add, row_count, 0);
|
||||
button_add->show();
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::GridWidgets::retranslate() {
|
||||
for (auto * w: widgets) {
|
||||
auto * gb = qobject_cast<QGroupBox *>(w);
|
||||
if (!gb) continue;
|
||||
gb->setTitle(PIVariantEditorBase::vtTr(Q2PIString(gb->property(property_name).toString())));
|
||||
}
|
||||
for (auto * l: labels) {
|
||||
QString nn = PIVariantEditorBase::vtTr(Q2PIString(l->property(property_name).toString()));
|
||||
if (!nn.isEmpty()) nn += ':';
|
||||
l->setText(nn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int PIValueTreeEdit::GridWidgets::removeRowEdits(int row) {
|
||||
int col = create_edit_buttons ? 1 : 0;
|
||||
for (int c = col; c < lay->columnCount(); ++c) {
|
||||
auto * li = lay->itemAtPosition(row, c);
|
||||
if (li) {
|
||||
QWidget * w = li->widget();
|
||||
if (w) {
|
||||
widgets.removeOne(w);
|
||||
QLabel * lbl = qobject_cast<QLabel *>(w);
|
||||
if (lbl) labels.removeOne(lbl);
|
||||
delete w;
|
||||
}
|
||||
}
|
||||
}
|
||||
return col;
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::GridWidgets::removeRow(int index) {
|
||||
if (!lay) return;
|
||||
if ((index < 0) || (index >= row_count) || (index >= lay->rowCount())) return;
|
||||
for (int c = 0; c < lay->columnCount(); ++c) {
|
||||
auto * li = lay->itemAtPosition(index, c);
|
||||
if (li) {
|
||||
QWidget * w = li->widget();
|
||||
if (w) {
|
||||
widgets.removeOne(w);
|
||||
QLabel * lbl = qobject_cast<QLabel *>(w);
|
||||
if (lbl) labels.removeOne(lbl);
|
||||
delete w;
|
||||
}
|
||||
}
|
||||
}
|
||||
--row_count;
|
||||
simplify();
|
||||
changed();
|
||||
}
|
||||
|
||||
|
||||
void PIValueTreeEdit::GridWidgets::simplify(const PIMap<int, int> & map) {
|
||||
struct Info {
|
||||
Qt::Alignment align;
|
||||
int row_span = 0;
|
||||
int col_span = 0;
|
||||
};
|
||||
if (!lay) return;
|
||||
QVector<QMap<int, QWidget *>> wg;
|
||||
QMap<QWidget *, Info> wa;
|
||||
for (int r = 0; r < lay->rowCount(); ++r) {
|
||||
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();
|
||||
Info info;
|
||||
info.align = li->alignment();
|
||||
int pos[4];
|
||||
lay->getItemPosition(lay->indexOf(li), &(pos[0]), &(pos[1]), &(pos[2]), &(pos[3]));
|
||||
info.row_span = pos[2];
|
||||
info.col_span = pos[3];
|
||||
wa[li->widget()] = info;
|
||||
c += (pos[3] - 1);
|
||||
}
|
||||
}
|
||||
if (!row.isEmpty()) wg << row;
|
||||
}
|
||||
delete lay;
|
||||
lay = new QGridLayout();
|
||||
lay->setContentsMargins(0, 0, 0, 0);
|
||||
int rindex = 0;
|
||||
for (int i = 0; i < wg.size(); ++i) {
|
||||
int mi = map.value(i, i);
|
||||
if (mi < 0 || mi >= wg.size()) continue;
|
||||
QMapIterator<int, QWidget *> it(wg[mi]);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
Info info = wa.value(it.value());
|
||||
lay->addWidget(it.value(), rindex, it.key(), info.row_span, info.col_span, info.align);
|
||||
}
|
||||
++rindex;
|
||||
}
|
||||
setLayout(lay);
|
||||
adjustSize();
|
||||
}
|
||||
Reference in New Issue
Block a user