mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-08-03 10:34:14 +02:00
Fix-PLC-Manager
This commit is contained in:
@@ -280,6 +280,11 @@ namespace autonum
|
|||||||
str.replace("%{plc_function}", dc.value("plc_function").toString());
|
str.replace("%{plc_function}", dc.value("plc_function").toString());
|
||||||
str.replace("%{plc_comment}", dc.value("plc_comment").toString());
|
str.replace("%{plc_comment}", dc.value("plc_comment").toString());
|
||||||
str.replace("%{plc_crossref}", dc.value("plc_crossref").toString());
|
str.replace("%{plc_crossref}", dc.value("plc_crossref").toString());
|
||||||
|
str.replace("%{plc_tc}", dc.value("plc_tc").toString());
|
||||||
|
str.replace("%{plc_t1}", dc.value("plc_t1").toString());
|
||||||
|
str.replace("%{plc_t2}", dc.value("plc_t2").toString());
|
||||||
|
str.replace("%{plc_t3}", dc.value("plc_t3").toString());
|
||||||
|
str.replace("%{plc_t4}", dc.value("plc_t4").toString());
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -240,7 +240,12 @@ void DynamicTextFieldEditor::fillInfoComboBox()
|
|||||||
QETInformation::ELMT_PLC_ADDRESS,
|
QETInformation::ELMT_PLC_ADDRESS,
|
||||||
QETInformation::ELMT_PLC_FUNCTION,
|
QETInformation::ELMT_PLC_FUNCTION,
|
||||||
QETInformation::ELMT_PLC_COMMENT,
|
QETInformation::ELMT_PLC_COMMENT,
|
||||||
QETInformation::ELMT_PLC_CROSSREF
|
QETInformation::ELMT_PLC_CROSSREF,
|
||||||
|
QETInformation::ELMT_PLC_TC,
|
||||||
|
QETInformation::ELMT_PLC_T1,
|
||||||
|
QETInformation::ELMT_PLC_T2,
|
||||||
|
QETInformation::ELMT_PLC_T3,
|
||||||
|
QETInformation::ELMT_PLC_T4
|
||||||
};
|
};
|
||||||
strl = plc_keys + strl;
|
strl = plc_keys + strl;
|
||||||
} else {
|
} else {
|
||||||
@@ -249,6 +254,11 @@ void DynamicTextFieldEditor::fillInfoComboBox()
|
|||||||
strl.removeAll(QETInformation::ELMT_PLC_FUNCTION);
|
strl.removeAll(QETInformation::ELMT_PLC_FUNCTION);
|
||||||
strl.removeAll(QETInformation::ELMT_PLC_COMMENT);
|
strl.removeAll(QETInformation::ELMT_PLC_COMMENT);
|
||||||
strl.removeAll(QETInformation::ELMT_PLC_CROSSREF);
|
strl.removeAll(QETInformation::ELMT_PLC_CROSSREF);
|
||||||
|
strl.removeAll(QETInformation::ELMT_PLC_TC);
|
||||||
|
strl.removeAll(QETInformation::ELMT_PLC_T1);
|
||||||
|
strl.removeAll(QETInformation::ELMT_PLC_T2);
|
||||||
|
strl.removeAll(QETInformation::ELMT_PLC_T3);
|
||||||
|
strl.removeAll(QETInformation::ELMT_PLC_T4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -780,7 +780,7 @@ void ElementPropertiesEditorWidget::createPlcConfigWidgets()
|
|||||||
|
|
||||||
auto *sb = new QSpinBox(m_plc_gb);
|
auto *sb = new QSpinBox(m_plc_gb);
|
||||||
sb->setMinimum(10);
|
sb->setMinimum(10);
|
||||||
sb->setMaximum(200);
|
sb->setMaximum(500);
|
||||||
sb->setValue(40);
|
sb->setValue(40);
|
||||||
sb->setSuffix(tr(" mm"));
|
sb->setSuffix(tr(" mm"));
|
||||||
m_plc_col_width_spinboxes.append(sb);
|
m_plc_col_width_spinboxes.append(sb);
|
||||||
|
|||||||
@@ -1396,6 +1396,23 @@ void Element::setElementInformations(DiagramContext dc)
|
|||||||
m_data.m_informations.addValue(QStringLiteral("label"), actual_label); //Update the label if there is a formula
|
m_data.m_informations.addValue(QStringLiteral("label"), actual_label); //Update the label if there is a formula
|
||||||
}
|
}
|
||||||
emit elementInfoChange(old_info, m_data.m_informations);
|
emit elementInfoChange(old_info, m_data.m_informations);
|
||||||
|
|
||||||
|
// Propagate label change to linked PLC slaves
|
||||||
|
if (m_data.m_type == ElementData::Master && m_data.m_master_type == ElementData::PLC)
|
||||||
|
{
|
||||||
|
if (!m_group_index_map.isEmpty()) {
|
||||||
|
const QString new_label = actualLabel();
|
||||||
|
for (auto it = m_group_index_map.constBegin(); it != m_group_index_map.constEnd(); ++it)
|
||||||
|
{
|
||||||
|
Element *slave = it.key();
|
||||||
|
if (!slave)
|
||||||
|
continue;
|
||||||
|
DiagramContext ctx = slave->elementInformations();
|
||||||
|
ctx.addValue(QETInformation::ELMT_LABEL, new_label);
|
||||||
|
slave->setElementInformations(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1433,7 +1450,9 @@ void Element::setElementData(ElementData data)
|
|||||||
{
|
{
|
||||||
const auto &new_plc = m_data.plcMasterData();
|
const auto &new_plc = m_data.plcMasterData();
|
||||||
bool plc_changed = (old_plc.ios != new_plc.ios);
|
bool plc_changed = (old_plc.ios != new_plc.ios);
|
||||||
if (plc_changed && !m_group_index_map.isEmpty())
|
bool label_changed = (old_info.value(QStringLiteral("label")) !=
|
||||||
|
m_data.m_informations.value(QStringLiteral("label")));
|
||||||
|
if (!m_group_index_map.isEmpty() && (plc_changed || label_changed))
|
||||||
{
|
{
|
||||||
for (auto it = m_group_index_map.constBegin(); it != m_group_index_map.constEnd(); ++it)
|
for (auto it = m_group_index_map.constBegin(); it != m_group_index_map.constEnd(); ++it)
|
||||||
{
|
{
|
||||||
@@ -1442,24 +1461,63 @@ void Element::setElementData(ElementData data)
|
|||||||
if (!slave || io_idx < 0 || io_idx >= new_plc.ios.size())
|
if (!slave || io_idx < 0 || io_idx >= new_plc.ios.size())
|
||||||
continue;
|
continue;
|
||||||
const auto &io = new_plc.ios.at(io_idx);
|
const auto &io = new_plc.ios.at(io_idx);
|
||||||
DiagramContext ctx = slave->elementInformations();
|
|
||||||
ctx.addValue(QETInformation::ELMT_PLC_TYPE,
|
if (plc_changed)
|
||||||
ElementData::translatedPlcIOType(io.type));
|
{
|
||||||
ctx.addValue(QETInformation::ELMT_PLC_ADDRESS, io.address);
|
DiagramContext ctx = slave->elementInformations();
|
||||||
ctx.addValue(QETInformation::ELMT_PLC_FUNCTION, io.functionText);
|
ctx.addValue(QETInformation::ELMT_PLC_TYPE,
|
||||||
ctx.addValue(QETInformation::ELMT_PLC_COMMENT, io.comment);
|
ElementData::translatedPlcIOType(io.type));
|
||||||
ctx.addValue(QETInformation::ELMT_PLC_CROSSREF,
|
ctx.addValue(QETInformation::ELMT_PLC_ADDRESS, io.address);
|
||||||
[&]() -> QString {
|
ctx.addValue(QETInformation::ELMT_PLC_FUNCTION, io.functionText);
|
||||||
if (!diagram() || !diagram()->project())
|
ctx.addValue(QETInformation::ELMT_PLC_COMMENT, io.comment);
|
||||||
return QString();
|
ctx.addValue(QETInformation::ELMT_PLC_CROSSREF,
|
||||||
XRefProperties xrp = diagram()->project()
|
[&]() -> QString {
|
||||||
->defaultXRefProperties("plc");
|
if (!diagram() || !diagram()->project())
|
||||||
autonum::sequentialNumbers seq;
|
return QString();
|
||||||
return autonum::AssignVariables::formulaToLabel(
|
XRefProperties xrp = diagram()->project()
|
||||||
xrp.slaveLabel(), seq, diagram(), this);
|
->defaultXRefProperties("plc");
|
||||||
}());
|
autonum::sequentialNumbers seq;
|
||||||
ctx.addValue(QETInformation::ELMT_LABEL, actualLabel());
|
return autonum::AssignVariables::formulaToLabel(
|
||||||
slave->setElementInformations(ctx);
|
xrp.slaveLabel(), seq, diagram(), this);
|
||||||
|
}());
|
||||||
|
ctx.addValue(QETInformation::ELMT_PLC_TC,
|
||||||
|
QString::number(io.terminalCount));
|
||||||
|
for (int t = 0; t < io.terminalCount && t < 4; ++t)
|
||||||
|
{
|
||||||
|
QString val = (t < io.terminals.size())
|
||||||
|
? io.terminals.at(t) : QString();
|
||||||
|
ctx.addValue(
|
||||||
|
QStringList({
|
||||||
|
QETInformation::ELMT_PLC_T1,
|
||||||
|
QETInformation::ELMT_PLC_T2,
|
||||||
|
QETInformation::ELMT_PLC_T3,
|
||||||
|
QETInformation::ELMT_PLC_T4
|
||||||
|
}).at(t), val);
|
||||||
|
}
|
||||||
|
slave->setElementInformations(ctx);
|
||||||
|
|
||||||
|
// Update master labels on slave terminals
|
||||||
|
QList<Terminal *> slave_terms = slave->terminals();
|
||||||
|
for (int t = 0; t < slave_terms.size(); ++t)
|
||||||
|
{
|
||||||
|
if (t < io.terminals.size())
|
||||||
|
{
|
||||||
|
slave_terms.at(t)->setUseMasterLabel(true);
|
||||||
|
slave_terms.at(t)->setMasterLabelIndex(t);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
slave_terms.at(t)->setUseMasterLabel(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (label_changed)
|
||||||
|
{
|
||||||
|
// Only label changed, update the label on the slave
|
||||||
|
DiagramContext ctx = slave->elementInformations();
|
||||||
|
ctx.addValue(QETInformation::ELMT_LABEL, actualLabel());
|
||||||
|
slave->setElementInformations(ctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1900,7 +1958,7 @@ void Element::drawPlcTable(QPainter *painter)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QRectF text_rect = cr.adjusted(1, 0, -1, 0);
|
QRectF text_rect = cr.adjusted(1, 0, -1, 0);
|
||||||
painter->drawText(text_rect, Qt::AlignLeft | Qt::AlignVCenter, cell_text);
|
painter->drawText(text_rect, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextWordWrap, cell_text);
|
||||||
|
|
||||||
cx += col_widths[col];
|
cx += col_widths[col];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -289,8 +289,17 @@ void Terminal::paint(
|
|||||||
painter->save();
|
painter->save();
|
||||||
painter->translate(label_pos);
|
painter->translate(label_pos);
|
||||||
painter->rotate(d->m_label_rotation);
|
painter->rotate(d->m_label_rotation);
|
||||||
QRectF text_rect(-text_size.width()/2.0, -text_size.height()/2.0,
|
|
||||||
text_size.width(), text_size.height());
|
qreal rx = 0, ry = 0;
|
||||||
|
if (d->m_label_halignment & Qt::AlignLeft) rx = 0;
|
||||||
|
else if (d->m_label_halignment & Qt::AlignHCenter) rx = -text_size.width() / 2.0;
|
||||||
|
else if (d->m_label_halignment & Qt::AlignRight) rx = -text_size.width();
|
||||||
|
|
||||||
|
if (d->m_label_valignment & Qt::AlignTop) ry = 0;
|
||||||
|
else if (d->m_label_valignment & Qt::AlignVCenter) ry = -text_size.height() / 2.0;
|
||||||
|
else if (d->m_label_valignment & Qt::AlignBottom) ry = -text_size.height();
|
||||||
|
|
||||||
|
QRectF text_rect(QPointF(rx, ry), text_size);
|
||||||
painter->drawText(text_rect, static_cast<int>(d->m_label_halignment | d->m_label_valignment), display_name);
|
painter->drawText(text_rect, static_cast<int>(d->m_label_halignment | d->m_label_valignment), display_name);
|
||||||
painter->restore();
|
painter->restore();
|
||||||
} else {
|
} else {
|
||||||
@@ -307,7 +316,7 @@ void Terminal::paint(
|
|||||||
if (d->m_label_frame) {
|
if (d->m_label_frame) {
|
||||||
painter->drawRect(text_rect.adjusted(-1, -1, 1, 1));
|
painter->drawRect(text_rect.adjusted(-1, -1, 1, 1));
|
||||||
}
|
}
|
||||||
painter->drawText(text_rect, static_cast<int>(Qt::AlignLeft | Qt::AlignTop), display_name);
|
painter->drawText(text_rect, static_cast<int>(d->m_label_halignment | d->m_label_valignment), display_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -816,12 +825,24 @@ QString Terminal::name() const
|
|||||||
if (elmt->linkType() == Element::Master) {
|
if (elmt->linkType() == Element::Master) {
|
||||||
int group_idx = elmt->groupIndexForElement(parent_element_);
|
int group_idx = elmt->groupIndexForElement(parent_element_);
|
||||||
if (group_idx >= 0) {
|
if (group_idx >= 0) {
|
||||||
const auto &groups = elmt->elementData().m_slave_contact_groups;
|
// For PLC masters, use io.terminals as labels
|
||||||
if (group_idx < groups.size()) {
|
if (elmt->elementData().m_master_type == ElementData::PLC) {
|
||||||
int label_idx = d->m_master_label_index;
|
const auto &plc_data = elmt->elementData().plcMasterData();
|
||||||
const QStringList &labels = groups.at(group_idx).labels;
|
if (group_idx < plc_data.ios.size()) {
|
||||||
if (label_idx >= 0 && label_idx < labels.size()) {
|
int label_idx = d->m_master_label_index;
|
||||||
return labels.at(label_idx);
|
const QStringList &labels = plc_data.ios.at(group_idx).terminals;
|
||||||
|
if (label_idx >= 0 && label_idx < labels.size()) {
|
||||||
|
return labels.at(label_idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const auto &groups = elmt->elementData().m_slave_contact_groups;
|
||||||
|
if (group_idx < groups.size()) {
|
||||||
|
int label_idx = d->m_master_label_index;
|
||||||
|
const QStringList &labels = groups.at(group_idx).labels;
|
||||||
|
if (label_idx >= 0 && label_idx < labels.size()) {
|
||||||
|
return labels.at(label_idx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -832,6 +853,16 @@ QString Terminal::name() const
|
|||||||
return d->m_name;
|
return d->m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Terminal::baseName
|
||||||
|
Return the original terminal name (T1, T2...) without master label override.
|
||||||
|
Used for sorting when linking.
|
||||||
|
*/
|
||||||
|
QString Terminal::baseName() const
|
||||||
|
{
|
||||||
|
return d->m_name;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Terminal::terminalType
|
@brief Terminal::terminalType
|
||||||
@return the type of this terminal (Generic, Inner, Outer, No, Nc, Common)
|
@return the type of this terminal (Generic, Inner, Outer, No, Nc, Common)
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ class Terminal : public QGraphicsObject
|
|||||||
Element *parentElement () const;
|
Element *parentElement () const;
|
||||||
QUuid uuid () const;
|
QUuid uuid () const;
|
||||||
QString name () const;
|
QString name () const;
|
||||||
|
QString baseName () const;
|
||||||
TerminalData::Type terminalType() const;
|
TerminalData::Type terminalType() const;
|
||||||
bool useMasterLabel() const { return d->m_use_master_label; }
|
bool useMasterLabel() const { return d->m_use_master_label; }
|
||||||
void setUseMasterLabel(bool use);
|
void setUseMasterLabel(bool use);
|
||||||
|
|||||||
@@ -130,6 +130,11 @@ namespace QETInformation
|
|||||||
static QString ELMT_PLC_FUNCTION = "plc_function";
|
static QString ELMT_PLC_FUNCTION = "plc_function";
|
||||||
static QString ELMT_PLC_COMMENT = "plc_comment";
|
static QString ELMT_PLC_COMMENT = "plc_comment";
|
||||||
static QString ELMT_PLC_CROSSREF = "plc_crossref";
|
static QString ELMT_PLC_CROSSREF = "plc_crossref";
|
||||||
|
static QString ELMT_PLC_TC = "plc_tc";
|
||||||
|
static QString ELMT_PLC_T1 = "plc_t1";
|
||||||
|
static QString ELMT_PLC_T2 = "plc_t2";
|
||||||
|
static QString ELMT_PLC_T3 = "plc_t3";
|
||||||
|
static QString ELMT_PLC_T4 = "plc_t4";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -978,7 +978,7 @@ void MasterPropertiesWidget::plcUpdateDisplaySettings()
|
|||||||
ElementData::PlcMasterData plc_data = ed.plcMasterData();
|
ElementData::PlcMasterData plc_data = ed.plcMasterData();
|
||||||
plc_data.ios.clear();
|
plc_data.ios.clear();
|
||||||
|
|
||||||
// Read IOs from table
|
// Read IOs from table, preserving terminal data from original IOs
|
||||||
for (int row = 0; row < m_plc_table->rowCount(); ++row) {
|
for (int row = 0; row < m_plc_table->rowCount(); ++row) {
|
||||||
ElementData::PlcIO io;
|
ElementData::PlcIO io;
|
||||||
|
|
||||||
@@ -1002,6 +1002,13 @@ void MasterPropertiesWidget::plcUpdateDisplaySettings()
|
|||||||
if (crossref_item)
|
if (crossref_item)
|
||||||
io.crossRef = crossref_item->text();
|
io.crossRef = crossref_item->text();
|
||||||
|
|
||||||
|
// Preserve terminal data from the original IO
|
||||||
|
if (row < ed.plcMasterData().ios.size()) {
|
||||||
|
const auto &orig_io = ed.plcMasterData().ios.at(row);
|
||||||
|
io.terminalCount = orig_io.terminalCount;
|
||||||
|
io.terminals = orig_io.terminals;
|
||||||
|
}
|
||||||
|
|
||||||
plc_data.ios.append(io);
|
plc_data.ios.append(io);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -406,22 +406,46 @@ void LinkElementCommand::makeLink(const QList<Element *> &element_list)
|
|||||||
elmt->setGroupIndexForElement(m_element, group_idx);
|
elmt->setGroupIndexForElement(m_element, group_idx);
|
||||||
|
|
||||||
// Set master labels on slave terminals
|
// Set master labels on slave terminals
|
||||||
const auto &groups = elmt->elementData().m_slave_contact_groups;
|
if (elmt->elementData().m_master_type == ElementData::PLC)
|
||||||
if (group_idx < groups.size())
|
|
||||||
{
|
{
|
||||||
const QStringList &labels = groups.at(group_idx).labels;
|
// For PLC masters, use io.terminals as labels
|
||||||
QList<Terminal *> slave_terms = m_element->terminals();
|
const auto &plc_data = elmt->elementData().plcMasterData();
|
||||||
// Sort terminals by name (T1, T2, T3...) to match label order
|
if (group_idx < plc_data.ios.size())
|
||||||
std::sort(slave_terms.begin(), slave_terms.end(),
|
|
||||||
[](Terminal *a, Terminal *b) {
|
|
||||||
return a->name() < b->name();
|
|
||||||
});
|
|
||||||
for (int i = 0; i < slave_terms.size(); ++i)
|
|
||||||
{
|
{
|
||||||
if (i < labels.size())
|
const QStringList &labels = plc_data.ios.at(group_idx).terminals;
|
||||||
|
QList<Terminal *> slave_terms = m_element->terminals();
|
||||||
|
std::sort(slave_terms.begin(), slave_terms.end(),
|
||||||
|
[](Terminal *a, Terminal *b) {
|
||||||
|
return a->baseName() < b->baseName();
|
||||||
|
});
|
||||||
|
for (int i = 0; i < slave_terms.size(); ++i)
|
||||||
{
|
{
|
||||||
slave_terms.at(i)->setUseMasterLabel(true);
|
if (i < labels.size())
|
||||||
slave_terms.at(i)->setMasterLabelIndex(i);
|
{
|
||||||
|
slave_terms.at(i)->setUseMasterLabel(true);
|
||||||
|
slave_terms.at(i)->setMasterLabelIndex(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto &groups = elmt->elementData().m_slave_contact_groups;
|
||||||
|
if (group_idx < groups.size())
|
||||||
|
{
|
||||||
|
const QStringList &labels = groups.at(group_idx).labels;
|
||||||
|
QList<Terminal *> slave_terms = m_element->terminals();
|
||||||
|
std::sort(slave_terms.begin(), slave_terms.end(),
|
||||||
|
[](Terminal *a, Terminal *b) {
|
||||||
|
return a->baseName() < b->baseName();
|
||||||
|
});
|
||||||
|
for (int i = 0; i < slave_terms.size(); ++i)
|
||||||
|
{
|
||||||
|
if (i < labels.size())
|
||||||
|
{
|
||||||
|
slave_terms.at(i)->setUseMasterLabel(true);
|
||||||
|
slave_terms.at(i)->setMasterLabelIndex(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -443,6 +467,20 @@ void LinkElementCommand::makeLink(const QList<Element *> &element_list)
|
|||||||
plcCrossRefText(elmt, m_element));
|
plcCrossRefText(elmt, m_element));
|
||||||
ctx.addValue(QETInformation::ELMT_LABEL,
|
ctx.addValue(QETInformation::ELMT_LABEL,
|
||||||
elmt->actualLabel());
|
elmt->actualLabel());
|
||||||
|
ctx.addValue(QETInformation::ELMT_PLC_TC,
|
||||||
|
QString::number(io.terminalCount));
|
||||||
|
for (int t = 0; t < io.terminalCount && t < 4; ++t)
|
||||||
|
{
|
||||||
|
QString val = (t < io.terminals.size())
|
||||||
|
? io.terminals.at(t) : QString();
|
||||||
|
ctx.addValue(
|
||||||
|
QStringList({
|
||||||
|
QETInformation::ELMT_PLC_T1,
|
||||||
|
QETInformation::ELMT_PLC_T2,
|
||||||
|
QETInformation::ELMT_PLC_T3,
|
||||||
|
QETInformation::ELMT_PLC_T4
|
||||||
|
}).at(t), val);
|
||||||
|
}
|
||||||
m_element->setElementInformations(ctx);
|
m_element->setElementInformations(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user