PIValueTreeEdit develop ...

This commit is contained in:
2022-12-13 21:44:44 +03:00
parent a1a001035f
commit 3d3892a126
9 changed files with 492 additions and 137 deletions

View File

@@ -1,24 +1,38 @@
#include "pivaluetree_edit.h" #include "pivaluetree_edit.h"
#include "ui_pivaluetree_edit_array.h"
#include "pivariant_edit.h"
#include "piqt.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 <QEvent>
#include <QFormLayout> #include <QFormLayout>
#include <QGroupBox> #include <QGroupBox>
const char property_name[] = "__name__";
PIValueTreeEdit::PIValueTreeEdit(QWidget * parent): QWidget(parent) { PIValueTreeEdit::PIValueTreeEdit(QWidget * parent): QWidget(parent) {
ui = new Ui::PIValueTreeEditArray(); widget_params = new QDialog();
grid = new GridWidgets(); ui_array = new Ui::PIValueTreeEditArray();
auto * lay = new QBoxLayout(QBoxLayout::TopToBottom); 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); lay->setContentsMargins(0, 0, 0, 0);
setLayout(lay); setLayout(lay);
} }
PIValueTreeEdit::~PIValueTreeEdit() { PIValueTreeEdit::~PIValueTreeEdit() {
delete ui;
delete grid; 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() { void PIValueTreeEdit::rollback() {
build(); 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() { void PIValueTreeEdit::removeAll() {
array_edits.clear(); array_edits.clear();
value_edits.clear(); value_edits.clear();
tree_edits.clear(); tree_edits.clear();
if (ui_array) { if (widget_array) {
ui->layoutArray->takeAt(0); ui_array->layoutArray->takeAt(0);
delete ui_array; delete widget_array;
ui_array = nullptr; widget_array = nullptr;
} }
QLayoutItem * child = nullptr; QLayoutItem * child = nullptr;
while ((child = layout()->takeAt(0)) != nullptr) { while ((child = layout()->takeAt(0)) != nullptr) {
@@ -70,25 +98,26 @@ void PIValueTreeEdit::removeAll() {
void PIValueTreeEdit::build() { void PIValueTreeEdit::build() {
removeAll(); removeAll();
//piCout << source.attributes().value(PIValueTree::attributeArrayType) << array_type; // piCout << source.attributes().value(PIValueTree::attributeArrayType) << array_type;
if (source.isArray()) { if (source.isArray()) {
ui_array = new QWidget(); grid->create_edit_buttons = false;
ui->setupUi(ui_array); widget_array = new QWidget();
ui->spinCount->setRange(source.attribute(PIValueTree::attributeArrayMinCount, 0).toInt(), ui_array->setupUi(widget_array);
source.attribute(PIValueTree::attributeArrayMaxCount, 65536).toInt()); ui_array->spinCount->setRange(source.attribute(PIValueTree::attributeArrayMinCount, 0).toInt(),
ui->spinCount->setValue(source.children().size_s()); source.attribute(PIValueTree::attributeArrayMaxCount, 65536).toInt());
ui->widgetEdit->setVisible(source.attribute(PIValueTree::attributeArrayResize, false).toBool()); ui_array->spinCount->setValue(source.children().size_s());
ui->layoutArray->addWidget(grid); 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()); uint array_type = PIVariant::typeIDFromName(source.attribute(PIValueTree::attributeArrayType).toString());
int index = 0; int index = 0;
for (const auto & i: source.children()) { for (const auto & i: source.children()) {
auto * ve = new PIVariantEdit(); auto * ve = new PIVariantEdit();
ve->setAttributes(source.attributes()); ve->setAttributes(source.attributes());
ve->setValue(i.value(), array_type); 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; 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); value = piMaxi(value, 0);
for (int i = grid->rowCount() - 1; i >= value; --i) for (int i = grid->rowCount() - 1; i >= value; --i)
grid->removeRow(i); grid->removeRow(i);
@@ -97,12 +126,13 @@ void PIValueTreeEdit::build() {
auto * ve = new PIVariantEdit(); auto * ve = new PIVariantEdit();
ve->setAttributes(source.attributes()); ve->setAttributes(source.attributes());
ve->setValue(PIVariant::fromType(array_type), array_type); 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; array_edits << ve;
} }
}); });
layout()->addWidget(ui_array); layout()->addWidget(widget_array);
} else { } else {
grid->create_edit_buttons = is_full_edit;
layout()->addWidget(grid); layout()->addWidget(grid);
for (const auto & i: source.children()) { for (const auto & i: source.children()) {
if (i.attribute(PIValueTree::attributeHidden, false).toBool()) continue; if (i.attribute(PIValueTree::attributeHidden, false).toBool()) continue;
@@ -110,12 +140,16 @@ void PIValueTreeEdit::build() {
if (i.name().isEmpty()) continue; if (i.name().isEmpty()) continue;
auto * l = new QLabel(PI2QString(i.name())); auto * l = new QLabel(PI2QString(i.name()));
l->setAlignment(Qt::AlignCenter); l->setAlignment(Qt::AlignCenter);
grid->add(l); grid->add(i, l);
continue; continue;
} }
if (i.hasChildren() || i.isArray()) { 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->setGroupingEnabled(is_grouping);
ve->setFullEditMode(is_full_edit);
ve->setValue(i); ve->setValue(i);
if (is_grouping) { if (is_grouping) {
auto * gb = new QGroupBox(); auto * gb = new QGroupBox();
@@ -127,16 +161,16 @@ void PIValueTreeEdit::build() {
gb->setChecked(true); gb->setChecked(true);
gb->setAlignment(Qt::AlignCenter); gb->setAlignment(Qt::AlignCenter);
connect(gb, &QGroupBox::toggled, ve, &QWidget::setVisible); connect(gb, &QGroupBox::toggled, ve, &QWidget::setVisible);
grid->add(gb); grid->add(i, gb);
} else { } 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; tree_edits[i.name()] = ve;
} else { } else {
auto * ve = new PIVariantEdit(); auto * ve = new PIVariantEdit();
ve->setAttributes(i.attributes()); ve->setAttributes(i.attributes());
ve->setValue(i.value()); 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; value_edits[i.name()] = ve;
} }
} }
@@ -146,8 +180,7 @@ void PIValueTreeEdit::build() {
void PIValueTreeEdit::applyValues() const { void PIValueTreeEdit::applyValues() const {
if (source.isArray()) { if (source.isArray()) {
if (array_edits.isNotEmpty()) if (array_edits.isNotEmpty()) source.mergeAttributes(array_edits[0]->defaultAttributes());
source.mergeAttributes(array_edits[0]->defaultAttributes());
source.clearChildren(); source.clearChildren();
for (int i = 0; i < array_edits.size_s(); ++i) for (int i = 0; i < array_edits.size_s(); ++i)
source.addChild({PIString::fromNumber(i), array_edits[i]->value()}); 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) { // PIValueTreeEdit::GridWidgets
if (!label.isEmpty())
label += ':'; 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 * l = new QLabel(label);
auto * c = new QLabel(comment); auto * c = new QLabel(comment);
l->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); l->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
c->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); c->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
w->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); w->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
lay->addWidget(l, row_count, 0, Qt::AlignVCenter | Qt::AlignRight); lay->addWidget(l, row_count, col++, Qt::AlignVCenter | Qt::AlignRight);
lay->addWidget(w, row_count, 1); lay->addWidget(w, row_count, col++);
lay->addWidget(c, row_count, 2, Qt::AlignVCenter | Qt::AlignLeft); lay->addWidget(c, row_count, col++, Qt::AlignVCenter | Qt::AlignLeft);
widgets << l << w << c; widgets << l << w << c;
labels << l;
++row_count; ++row_count;
} }
void PIValueTreeEdit::GridWidgets::add(QWidget * w) { void PIValueTreeEdit::GridWidgets::add(const PIValueTree & vt, QWidget * w) {
lay->addWidget(w, row_count, 0, 1, -1); int col = beginRow(vt);
lay->addWidget(w, row_count, col, 1, -1);
widgets << w; widgets << w;
++row_count; ++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() { void PIValueTreeEdit::GridWidgets::clear() {
piDeleteAllAndClear(widgets); piDeleteAllAndClear(widgets);
if (lay) labels.clear();
delete lay; if (lay) delete lay;
lay = new QGridLayout(); lay = new QGridLayout();
lay->setContentsMargins(0, 0, 0, 0); lay->setContentsMargins(0, 0, 0, 0);
setLayout(lay); setLayout(lay);
@@ -204,13 +341,14 @@ void PIValueTreeEdit::GridWidgets::clear() {
void PIValueTreeEdit::GridWidgets::removeRow(int index) { void PIValueTreeEdit::GridWidgets::removeRow(int index) {
if (!lay) return; if (!lay || index < 0 || row_count <= index) return;
if (row_count <= index) return;
for (int c = 0; c < lay->columnCount(); ++c) { for (int c = 0; c < lay->columnCount(); ++c) {
auto * li = lay->itemAtPosition(index, c); auto * li = lay->itemAtPosition(index, c);
if (li) { if (li) {
if (li->widget()) { if (li->widget()) {
widgets.removeOne(li->widget()); widgets.removeOne(li->widget());
QLabel * lbl = qobject_cast<QLabel *>(li->widget());
if (lbl) labels.removeOne(lbl);
delete li->widget(); delete li->widget();
} }
delete li; delete li;
@@ -223,27 +361,26 @@ void PIValueTreeEdit::GridWidgets::removeRow(int index) {
void PIValueTreeEdit::GridWidgets::simplify() { void PIValueTreeEdit::GridWidgets::simplify() {
if (!lay) return; if (!lay) return;
QVector<QMap<int, QWidget*>> wg; QVector<QMap<int, QWidget *>> wg;
QMap<QWidget*, Qt::Alignment> wa; QMap<QWidget *, Qt::Alignment> wa;
for (int r = 0; r < lay->rowCount(); ++r) { for (int r = 0; r < lay->rowCount(); ++r) {
QMap<int, QWidget*> row; QMap<int, QWidget *> row;
for (int c = 0; c < lay->columnCount(); ++c) { for (int c = 0; c < lay->columnCount(); ++c) {
auto * li = lay->itemAtPosition(r, c); auto * li = lay->itemAtPosition(r, c);
if (!li) continue; if (!li) continue;
if (li->widget()) { if (li->widget()) {
row[c] = li->widget(); row[c] = li->widget();
wa[li->widget()] = li->alignment(); wa[li->widget()] = li->alignment();
} }
} }
if (!row.isEmpty()) if (!row.isEmpty()) wg << row;
wg << row;
} }
delete lay; delete lay;
lay = new QGridLayout(); lay = new QGridLayout();
lay->setContentsMargins(0, 0, 0, 0); lay->setContentsMargins(0, 0, 0, 0);
int rindex = 0; int rindex = 0;
for (const auto & row: wg) { for (const auto & row: wg) {
QMapIterator<int, QWidget*> it(row); QMapIterator<int, QWidget *> it(row);
while (it.hasNext()) { while (it.hasNext()) {
it.next(); it.next();
lay->addWidget(it.value(), rindex, it.key(), wa.value(it.value())); lay->addWidget(it.value(), rindex, it.key(), wa.value(it.value()));

View File

@@ -20,18 +20,25 @@
#ifndef pivaluetree_edit_H #ifndef pivaluetree_edit_H
#define pivaluetree_edit_H #define pivaluetree_edit_H
#include <QWidget>
#include <QLabel>
#include "pivaluetree.h" #include "pivaluetree.h"
#include "qad_piqt_utils_export.h" #include "qad_piqt_utils_export.h"
#include "qicon.h"
#include "qmenu.h"
#include <QLabel>
#include <QWidget>
class QGridLayout; class QGridLayout;
class QToolButton;
class PIVariantEdit; class PIVariantEdit;
namespace Ui { namespace Ui {
class PIValueTreeEditArray; class PIValueTreeEditArray;
} class PIValueTreeEditParameters;
} // namespace Ui
class QAD_PIQT_UTILS_EXPORT PIValueTreeEdit: public QWidget { class QAD_PIQT_UTILS_EXPORT PIValueTreeEdit: public QWidget {
Q_OBJECT
public: public:
PIValueTreeEdit(QWidget * parent = nullptr); PIValueTreeEdit(QWidget * parent = nullptr);
~PIValueTreeEdit(); ~PIValueTreeEdit();
@@ -43,39 +50,61 @@ public:
void setValue(const PIValueTree & v); void setValue(const PIValueTree & v);
PIValueTree value() const; PIValueTree value() const;
bool isGroupingEnabled() const { return is_grouping; }
void setGroupingEnabled(bool yes); void setGroupingEnabled(bool yes);
bool isFullEditMode() const { return is_full_edit; }
void setFullEditMode(bool yes);
void rollback(); void rollback();
void clear(); void clear();
private: private:
void changeEvent(QEvent * e) override;
void removeAll(); void removeAll();
void build(); void build();
void applyValues() const; void applyValues() const;
void actionTriggered(QToolButton * button, const PIString & vn, QAction * a);
class GridWidgets: public QWidget { class GridWidgets: public QWidget {
public: public:
int rowCount() const {return row_count;} GridWidgets(Ui::PIValueTreeEditParameters * ui_);
int rowCount() const { return row_count; }
int getRow(QWidget * w) const;
void removeRow(int index); void removeRow(int index);
void add(QString label, QWidget * w, const QString & comment); void add(const PIValueTree & vt, QString label, QWidget * w, const QString & comment);
void add(QWidget * w); void add(const PIValueTree & vt, QWidget * w);
int beginRow(const PIValueTree & vt);
void rename(QString prev_name, QString new_name);
void clear(); void clear();
bool create_edit_buttons = false;
PIValueTreeEdit * parent;
private: private:
void simplify(); void simplify();
int row_count = 0;
int row_count = 0;
QGridLayout * lay = nullptr; QGridLayout * lay = nullptr;
QMenu conf_menu;
QWidgetList widgets; QWidgetList widgets;
QList<QLabel *> labels;
QIcon icon_conf;
Ui::PIValueTreeEditParameters * ui_params;
}; };
QWidget * ui_array = nullptr; QWidget * widget_array = nullptr;
PIVector<PIVariantEdit*> array_edits; QDialog * widget_params;
PIMap<PIString, PIVariantEdit*> value_edits; PIStringList root_path;
PIMap<PIString, PIValueTreeEdit*> tree_edits; PIVector<PIVariantEdit *> array_edits;
Ui::PIValueTreeEditArray * ui; PIMap<PIString, PIVariantEdit *> value_edits;
PIMap<PIString, PIValueTreeEdit *> tree_edits;
Ui::PIValueTreeEditArray * ui_array;
Ui::PIValueTreeEditParameters * ui_params;
GridWidgets * grid = nullptr; GridWidgets * grid = nullptr;
mutable PIValueTree source; mutable PIValueTree source;
bool is_grouping = true; int last_IDs_count = -1;
bool is_grouping = true, is_full_edit = false;
}; };

View File

@@ -96,7 +96,5 @@
</widget> </widget>
<resources/> <resources/>
<connections/> <connections/>
<slots> <slots/>
<slot>recreateConnection()</slot>
</slots>
</ui> </ui>

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PIValueTreeEditParameters</class>
<widget class="QDialog" name="PIValueTreeEditParameters">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>395</width>
<height>172</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QFormLayout" name="formLayout">
<property name="labelAlignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="checkArray">
<property name="text">
<string>Array</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Type:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="EComboBox" name="comboType"/>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
<action name="actionRemove">
<property name="icon">
<iconset resource="../blockview/qad_blockview.qrc">
<normaloff>:/icons/edit-delete.png</normaloff>:/icons/edit-delete.png</iconset>
</property>
<property name="text">
<string>Remove</string>
</property>
</action>
<action name="actionChange">
<property name="icon">
<iconset resource="../application/qad_application.qrc">
<normaloff>:/icons/configure.png</normaloff>:/icons/configure.png</iconset>
</property>
<property name="text">
<string>Change ...</string>
</property>
</action>
<action name="actionRename">
<property name="icon">
<iconset resource="../graphic/qad_graphic.qrc">
<normaloff>:/icons/border-line.png</normaloff>:/icons/border-line.png</iconset>
</property>
<property name="text">
<string>Rename ...</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>EComboBox</class>
<extends>QComboBox</extends>
<header>ecombobox.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../application/qad_application.qrc"/>
<include location="../blockview/qad_blockview.qrc"/>
<include location="../graphic/qad_graphic.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>PIValueTreeEditParameters</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>247</x>
<y>276</y>
</hint>
<hint type="destinationlabel">
<x>196</x>
<y>221</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>PIValueTreeEditParameters</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>317</x>
<y>269</y>
</hint>
<hint type="destinationlabel">
<x>291</x>
<y>222</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -1,5 +1,7 @@
#include "pivariant_edit.h" #include "pivariant_edit.h"
#include "piqt.h" #include "piqt.h"
#include <QEvent> #include <QEvent>
@@ -12,6 +14,11 @@ PIVariantEditorBase * PIVariantEditorBase::createEditor(uint type_id) {
} }
bool PIVariantEditorBase::editorExists(uint type_id) {
return factories().value(type_id, nullptr);
}
void PIVariantEditorBase::createBoxLayout(QBoxLayout::Direction d) { void PIVariantEditorBase::createBoxLayout(QBoxLayout::Direction d) {
auto * l = new QBoxLayout(d); auto * l = new QBoxLayout(d);
l->setContentsMargins(0, 0, 0, 0); l->setContentsMargins(0, 0, 0, 0);
@@ -20,20 +27,17 @@ void PIVariantEditorBase::createBoxLayout(QBoxLayout::Direction d) {
void PIVariantEditorBase::changeEvent(QEvent * e) { void PIVariantEditorBase::changeEvent(QEvent * e) {
if (e->type() == QEvent::LanguageChange) if (e->type() == QEvent::LanguageChange) retranslate();
retranslate();
QWidget::changeEvent(e); QWidget::changeEvent(e);
} }
PIMap<uint, PIVariantEditorBase*(*)()> & PIVariantEditorBase::factories() { PIMap<uint, PIVariantEditorBase * (*)()> & PIVariantEditorBase::factories() {
static PIMap<uint, PIVariantEditorBase*(*)()> ret; static PIMap<uint, PIVariantEditorBase * (*)()> ret;
return ret; return ret;
} }
PIVariantEdit::PIVariantEdit(QWidget * parent): QWidget(parent) { PIVariantEdit::PIVariantEdit(QWidget * parent): QWidget(parent) {
label = new QLabel(); label = new QLabel();
label->setAlignment(Qt::AlignCenter); label->setAlignment(Qt::AlignCenter);
@@ -54,7 +58,7 @@ void PIVariantEdit::setValue(const PIVariant & v, uint type_id) {
if (current_type_id != type_id || !editor) { if (current_type_id != type_id || !editor) {
if (editor) delete editor; if (editor) delete editor;
current_type_id = type_id; current_type_id = type_id;
editor = PIVariantEditorBase::createEditor(current_type_id); editor = PIVariantEditorBase::createEditor(current_type_id);
if (editor) { if (editor) {
editor->applyAttributes(_attributes); editor->applyAttributes(_attributes);
layout()->removeWidget(label); layout()->removeWidget(label);
@@ -88,3 +92,9 @@ PIVariantMap PIVariantEdit::defaultAttributes() const {
if (!editor) return PIVariantMap(); if (!editor) return PIVariantMap();
return editor->defaultAttributes(); return editor->defaultAttributes();
} }
void PIVariantEdit::setFullEditMode(bool on) {
if (!editor) return;
editor->setFullEditMode(on);
}

View File

@@ -20,43 +20,47 @@
#ifndef pivariant_edit_H #ifndef pivariant_edit_H
#define pivariant_edit_H #define pivariant_edit_H
#include <QWidget>
#include <QBoxLayout>
#include <QLabel>
#include "pivariant.h" #include "pivariant.h"
#include "qad_piqt_utils_export.h" #include "qad_piqt_utils_export.h"
#define REGISTER_PIVARIANTEDITOR(type_name, class_name) \ #include <QBoxLayout>
STATIC_INITIALIZER_BEGIN \ #include <QLabel>
#include <QWidget>
#define REGISTER_PIVARIANTEDITOR(type_name, class_name) \
STATIC_INITIALIZER_BEGIN \
PIVariantEditorBase::registerEditor<class_name>(PIVariant::typeIDFromName(PIStringAscii(#type_name))); \ PIVariantEditorBase::registerEditor<class_name>(PIVariant::typeIDFromName(PIStringAscii(#type_name))); \
STATIC_INITIALIZER_END \ STATIC_INITIALIZER_END
class PIVariantEdit; class PIVariantEdit;
class QAD_PIQT_UTILS_EXPORT PIVariantEditorBase: public QWidget { class QAD_PIQT_UTILS_EXPORT PIVariantEditorBase: public QWidget {
friend class PIVariantEdit; friend class PIVariantEdit;
public: public:
PIVariantEditorBase() {createBoxLayout();} PIVariantEditorBase() { createBoxLayout(); }
virtual ~PIVariantEditorBase() {} virtual ~PIVariantEditorBase() {}
virtual void setValue(const PIVariant & v) = 0; virtual void setValue(const PIVariant & v) = 0;
virtual PIVariant value() const = 0; virtual PIVariant value() const = 0;
virtual PIVariantMap defaultAttributes() const {return PIVariantMap();} virtual PIVariantMap defaultAttributes() const { return PIVariantMap(); }
template <typename T> template<typename T>
static void registerEditor(uint type_id) { static void registerEditor(uint type_id) {
if (factories().contains(type_id)) { if (factories().contains(type_id)) {
piCout << "[PIVariantEditorBase::registerEditor] Editor with typeID" << type_id << "already registered, ignore"; piCout << "[PIVariantEditorBase::registerEditor] Editor with typeID" << type_id << "already registered, ignore";
return; return;
} }
factories()[type_id] = []()->PIVariantEditorBase*{return new T();}; factories()[type_id] = []() -> PIVariantEditorBase * { return new T(); };
} }
static PIVariantEditorBase * createEditor(uint type_id); static PIVariantEditorBase * createEditor(uint type_id);
static bool editorExists(uint type_id);
protected: protected:
void createBoxLayout(QBoxLayout::Direction d = QBoxLayout::LeftToRight); void createBoxLayout(QBoxLayout::Direction d = QBoxLayout::LeftToRight);
virtual void setFullEditMode(bool on) {}
virtual void applyAttributes(const PIVariantMap & a) {} virtual void applyAttributes(const PIVariantMap & a) {}
virtual void retranslate() {} virtual void retranslate() {}
@@ -64,8 +68,7 @@ protected:
private: private:
void changeEvent(QEvent * e) override; void changeEvent(QEvent * e) override;
static PIMap<uint, PIVariantEditorBase*(*)()> & factories(); static PIMap<uint, PIVariantEditorBase * (*)()> & factories();
}; };
@@ -80,12 +83,13 @@ public:
void setAttributes(const PIVariantMap & a); void setAttributes(const PIVariantMap & a);
PIVariantMap defaultAttributes() const; PIVariantMap defaultAttributes() const;
void setFullEditMode(bool on);
private: private:
PIVariantEditorBase * editor = nullptr; PIVariantEditorBase * editor = nullptr;
PIVariantMap _attributes; PIVariantMap _attributes;
QLabel * label; QLabel * label;
uint current_type_id = -1; uint current_type_id = -1;
}; };

View File

@@ -1,32 +1,35 @@
#include "pivariant_edit_widgets.h" #include "pivariant_edit_widgets.h"
#include "pivarianttypes.h"
#include "pivaluetree.h" #include "pivaluetree.h"
#include "pivarianttypes.h"
#include <QEvent> #include <QEvent>
#include <QMessageBox> #include <QMessageBox>
REGISTER_PIVARIANTEDITOR(bool, PIVariantEditors::Bool); REGISTER_PIVARIANTEDITOR(bool, PIVariantEditors::Bool);
REGISTER_PIVARIANTEDITOR( short, PIVariantEditors::Int); REGISTER_PIVARIANTEDITOR(short, PIVariantEditors::Int);
REGISTER_PIVARIANTEDITOR(ushort, PIVariantEditors::Int); REGISTER_PIVARIANTEDITOR(ushort, PIVariantEditors::Int);
REGISTER_PIVARIANTEDITOR( int, PIVariantEditors::Int); REGISTER_PIVARIANTEDITOR(int, PIVariantEditors::Int);
REGISTER_PIVARIANTEDITOR(uint, PIVariantEditors::Int); REGISTER_PIVARIANTEDITOR(uint, PIVariantEditors::Int);
REGISTER_PIVARIANTEDITOR(float , PIVariantEditors::Double); REGISTER_PIVARIANTEDITOR(float, PIVariantEditors::Double);
REGISTER_PIVARIANTEDITOR(double, PIVariantEditors::Double); REGISTER_PIVARIANTEDITOR(double, PIVariantEditors::Double);
REGISTER_PIVARIANTEDITOR(PIString, PIVariantEditors::String); REGISTER_PIVARIANTEDITOR(PIString, PIVariantEditors::String);
REGISTER_PIVARIANTEDITOR(PITime, PIVariantEditors::Time); REGISTER_PIVARIANTEDITOR(PITime, PIVariantEditors::Time);
REGISTER_PIVARIANTEDITOR(PIDate, PIVariantEditors::Date); REGISTER_PIVARIANTEDITOR(PIDate, PIVariantEditors::Date);
REGISTER_PIVARIANTEDITOR(PIDateTime, PIVariantEditors::DateTime); REGISTER_PIVARIANTEDITOR(PIDateTime, PIVariantEditors::DateTime);
REGISTER_PIVARIANTEDITOR(PIVariantTypes::Color, PIVariantEditors::Color); REGISTER_PIVARIANTEDITOR(PIVariantTypes::Color, PIVariantEditors::Color);
REGISTER_PIVARIANTEDITOR(PIVariantTypes::Enum, PIVariantEditors::Enum);
// PIVariantEditors::Int
PIVariantMap PIVariantEditors::Int::defaultAttributes() const { PIVariantMap PIVariantEditors::Int::defaultAttributes() const {
return { return {
{PIValueTree::attributeMinimum, widget->minimum()}, {PIValueTree::attributeMinimum, widget->minimum() },
{PIValueTree::attributeMaximum, widget->maximum()}, {PIValueTree::attributeMaximum, widget->maximum() },
{PIValueTree::attributeSingleStep, widget->singleStep()}, {PIValueTree::attributeSingleStep, widget->singleStep() },
{PIValueTree::attributePrefix, Q2PIString(widget->prefix())}, {PIValueTree::attributePrefix, Q2PIString(widget->prefix())},
{PIValueTree::attributeSuffix, Q2PIString(widget->suffix())}, {PIValueTree::attributeSuffix, Q2PIString(widget->suffix())},
}; };
} }
@@ -41,16 +44,16 @@ void PIVariantEditors::Int::applyAttributes(const PIVariantMap & a) {
} }
// PIVariantEditors::Double
PIVariantMap PIVariantEditors::Double::defaultAttributes() const { PIVariantMap PIVariantEditors::Double::defaultAttributes() const {
return { return {
{PIValueTree::attributeMinimum, widget->minimum()}, {PIValueTree::attributeMinimum, widget->minimum() },
{PIValueTree::attributeMaximum, widget->maximum()}, {PIValueTree::attributeMaximum, widget->maximum() },
{PIValueTree::attributeSingleStep, widget->singleStep()}, {PIValueTree::attributeSingleStep, widget->singleStep() },
{PIValueTree::attributeDecimals, widget->decimals()}, {PIValueTree::attributeDecimals, widget->decimals() },
{PIValueTree::attributePrefix, Q2PIString(widget->prefix())}, {PIValueTree::attributePrefix, Q2PIString(widget->prefix())},
{PIValueTree::attributeSuffix, Q2PIString(widget->suffix())}, {PIValueTree::attributeSuffix, Q2PIString(widget->suffix())},
}; };
} }
@@ -66,11 +69,10 @@ void PIVariantEditors::Double::applyAttributes(const PIVariantMap & a) {
} }
// PIVariantEditors::String
PIVariantMap PIVariantEditors::String::defaultAttributes() const { PIVariantMap PIVariantEditors::String::defaultAttributes() const {
return { return {};
};
} }
@@ -79,7 +81,7 @@ void PIVariantEditors::String::applyAttributes(const PIVariantMap & a) {
} }
// PIVariantEditors::Color
PIVariantMap PIVariantEditors::Color::defaultAttributes() const { PIVariantMap PIVariantEditors::Color::defaultAttributes() const {
return { return {
@@ -94,22 +96,46 @@ void PIVariantEditors::Color::applyAttributes(const PIVariantMap & a) {
} }
// PIVariantEditors::Time
void PIVariantEditors::Time::applyAttributes(const PIVariantMap & a) { void PIVariantEditors::Time::applyAttributes(const PIVariantMap & a) {
widget->setReadOnly(a.value(PIValueTree::attributeReadOnly, widget->isReadOnly()).toBool()); widget->setReadOnly(a.value(PIValueTree::attributeReadOnly, widget->isReadOnly()).toBool());
} }
// PIVariantEditors::Date
void PIVariantEditors::Date::applyAttributes(const PIVariantMap & a) { void PIVariantEditors::Date::applyAttributes(const PIVariantMap & a) {
widget->setReadOnly(a.value(PIValueTree::attributeReadOnly, widget->isReadOnly()).toBool()); widget->setReadOnly(a.value(PIValueTree::attributeReadOnly, widget->isReadOnly()).toBool());
} }
// PIVariantEditors::DateTime
void PIVariantEditors::DateTime::applyAttributes(const PIVariantMap & a) { void PIVariantEditors::DateTime::applyAttributes(const PIVariantMap & a) {
widget->setReadOnly(a.value(PIValueTree::attributeReadOnly, widget->isReadOnly()).toBool()); widget->setReadOnly(a.value(PIValueTree::attributeReadOnly, widget->isReadOnly()).toBool());
} }
// PIVariantEditors::Enum
void PIVariantEditors::Enum::setValue(const PIVariant & v) {
src = v.toEnum();
int sv = src.selectedValue();
widget->clear();
for (const auto & e: src.enum_list) {
widget->addItem(PI2QString(e.name), e.value);
if (e.value == sv) widget->setCurrentIndex(widget->count() - 1);
}
}
PIVariant PIVariantEditors::Enum::value() const {
src.selectValue(widget->currentData().toInt());
return src;
}
void PIVariantEditors::Enum::applyAttributes(const PIVariantMap & a) {
widget->setEnabled(!a.value(PIValueTree::attributeReadOnly, !widget->isEnabled()).toBool());
}

View File

@@ -21,14 +21,16 @@
#define pivariant_edit_widgets_H #define pivariant_edit_widgets_H
#include "pivariant_edit.h" #include "pivariant_edit.h"
#include <piqt.h>
#include <QCheckBox> #include <QCheckBox>
#include <QSpinBox> #include <QComboBox>
#include <QDateEdit>
#include <QDoubleSpinBox> #include <QDoubleSpinBox>
#include <QSpinBox>
#include <QTimeEdit>
#include <clineedit.h> #include <clineedit.h>
#include <colorbutton.h> #include <colorbutton.h>
#include <QTimeEdit> #include <piqt.h>
#include <QDateEdit>
namespace PIVariantEditors { namespace PIVariantEditors {
@@ -39,8 +41,9 @@ public:
widget = new QCheckBox(); widget = new QCheckBox();
layout()->addWidget(widget); layout()->addWidget(widget);
} }
void setValue(const PIVariant & v) override {widget->setChecked(v.toBool());} void setValue(const PIVariant & v) override { widget->setChecked(v.toBool()); }
PIVariant value() const override {return widget->isChecked();} PIVariant value() const override { return widget->isChecked(); }
private: private:
QCheckBox * widget; QCheckBox * widget;
}; };
@@ -53,9 +56,10 @@ public:
widget->setRange(-std::numeric_limits<int>::max(), std::numeric_limits<int>::max()); widget->setRange(-std::numeric_limits<int>::max(), std::numeric_limits<int>::max());
layout()->addWidget(widget); layout()->addWidget(widget);
} }
void setValue(const PIVariant & v) override {widget->setValue(v.toInt());} void setValue(const PIVariant & v) override { widget->setValue(v.toInt()); }
PIVariant value() const override {return widget->value();} PIVariant value() const override { return widget->value(); }
PIVariantMap defaultAttributes() const override; PIVariantMap defaultAttributes() const override;
private: private:
void applyAttributes(const PIVariantMap & a) override; void applyAttributes(const PIVariantMap & a) override;
QSpinBox * widget; QSpinBox * widget;
@@ -69,13 +73,13 @@ public:
widget->setRange(-std::numeric_limits<float>::max(), std::numeric_limits<float>::max()); widget->setRange(-std::numeric_limits<float>::max(), std::numeric_limits<float>::max());
layout()->addWidget(widget); layout()->addWidget(widget);
} }
void setValue(const PIVariant & v) override {widget->setValue(v.toDouble());} void setValue(const PIVariant & v) override { widget->setValue(v.toDouble()); }
PIVariant value() const override {return widget->value();} PIVariant value() const override { return widget->value(); }
PIVariantMap defaultAttributes() const override; PIVariantMap defaultAttributes() const override;
private: private:
void applyAttributes(const PIVariantMap & a) override; void applyAttributes(const PIVariantMap & a) override;
QDoubleSpinBox * widget; QDoubleSpinBox * widget;
}; };
@@ -85,13 +89,13 @@ public:
widget = new CLineEdit(); widget = new CLineEdit();
layout()->addWidget(widget); layout()->addWidget(widget);
} }
void setValue(const PIVariant & v) override {widget->setText(PI2QString(v.toString()));} void setValue(const PIVariant & v) override { widget->setText(PI2QString(v.toString())); }
PIVariant value() const override {return Q2PIString(widget->text());} PIVariant value() const override { return Q2PIString(widget->text()); }
PIVariantMap defaultAttributes() const override; PIVariantMap defaultAttributes() const override;
private: private:
void applyAttributes(const PIVariantMap & a) override; void applyAttributes(const PIVariantMap & a) override;
CLineEdit * widget; CLineEdit * widget;
}; };
@@ -101,9 +105,10 @@ public:
widget = new ColorButton(); widget = new ColorButton();
layout()->addWidget(widget); layout()->addWidget(widget);
} }
void setValue(const PIVariant & v) override {widget->setColor(PI2QColor(v.toColor()));} void setValue(const PIVariant & v) override { widget->setColor(PI2QColor(v.toColor())); }
PIVariant value() const override {return Q2PIColor(widget->color());} PIVariant value() const override { return Q2PIColor(widget->color()); }
PIVariantMap defaultAttributes() const override; PIVariantMap defaultAttributes() const override;
private: private:
void applyAttributes(const PIVariantMap & a) override; void applyAttributes(const PIVariantMap & a) override;
ColorButton * widget; ColorButton * widget;
@@ -117,9 +122,10 @@ public:
widget->setDisplayFormat("h:mm:ss"); widget->setDisplayFormat("h:mm:ss");
layout()->addWidget(widget); layout()->addWidget(widget);
} }
void setValue(const PIVariant & v) override {widget->setTime(PI2QTime(v.toTime()));} void setValue(const PIVariant & v) override { widget->setTime(PI2QTime(v.toTime())); }
PIVariant value() const override {return Q2PITime(widget->time());} PIVariant value() const override { return Q2PITime(widget->time()); }
PIVariantMap defaultAttributes() const override {return {};} PIVariantMap defaultAttributes() const override { return {}; }
private: private:
void applyAttributes(const PIVariantMap & a) override; void applyAttributes(const PIVariantMap & a) override;
QTimeEdit * widget; QTimeEdit * widget;
@@ -133,9 +139,10 @@ public:
widget->setDisplayFormat("d.MM.yyyy"); widget->setDisplayFormat("d.MM.yyyy");
layout()->addWidget(widget); layout()->addWidget(widget);
} }
void setValue(const PIVariant & v) override {widget->setDate(PI2QDate(v.toDate()));} void setValue(const PIVariant & v) override { widget->setDate(PI2QDate(v.toDate())); }
PIVariant value() const override {return Q2PIDate(widget->date());} PIVariant value() const override { return Q2PIDate(widget->date()); }
PIVariantMap defaultAttributes() const override {return {};} PIVariantMap defaultAttributes() const override { return {}; }
private: private:
void applyAttributes(const PIVariantMap & a) override; void applyAttributes(const PIVariantMap & a) override;
QDateEdit * widget; QDateEdit * widget;
@@ -149,16 +156,34 @@ public:
widget->setDisplayFormat("d.MM.yyyy h:mm:ss"); widget->setDisplayFormat("d.MM.yyyy h:mm:ss");
layout()->addWidget(widget); layout()->addWidget(widget);
} }
void setValue(const PIVariant & v) override {widget->setDateTime(PI2QDateTime(v.toDateTime()));} void setValue(const PIVariant & v) override { widget->setDateTime(PI2QDateTime(v.toDateTime())); }
PIVariant value() const override {return Q2PIDateTime(widget->dateTime());} PIVariant value() const override { return Q2PIDateTime(widget->dateTime()); }
PIVariantMap defaultAttributes() const override {return {};} PIVariantMap defaultAttributes() const override { return {}; }
private: private:
void applyAttributes(const PIVariantMap & a) override; void applyAttributes(const PIVariantMap & a) override;
QDateTimeEdit * widget; QDateTimeEdit * widget;
}; };
class QAD_PIQT_UTILS_EXPORT Enum: public PIVariantEditorBase {
public:
Enum() {
widget = new QComboBox();
layout()->addWidget(widget);
}
void setValue(const PIVariant & v) override;
PIVariant value() const override;
PIVariantMap defaultAttributes() const override { return {}; }
private:
void applyAttributes(const PIVariantMap & a) override;
mutable PIVariantTypes::Enum src;
QComboBox * widget;
}; };
}; // namespace PIVariantEditors
#endif #endif

View File

@@ -0,0 +1,6 @@
<RCC>
<qresource prefix="/">
<file>../../icons/configure.png</file>
<file>../../icons/border-line.png</file>
</qresource>
</RCC>