fix table synchronize
This commit is contained in:
parent
ccb362defb
commit
1b1dbac4bb
|
|
@ -28,6 +28,9 @@ public:
|
|||
void setModelController(FixedPortsModel* p){_curModelController = p;}
|
||||
auto getModelController() {return _curModelController;}
|
||||
void setExtendProperty(PropertyStateInfo info) {_extendInfo = info;} //设置跨组别使用的公共变量(ct,pt使用extend绕组信息)
|
||||
virtual void clearData(){};
|
||||
|
||||
QJsonObject parseCTWindingDefaultValue(const QVariant &value); //QVariant类型到QJsonObject转换(数据库读取的是var是QString)
|
||||
protected:
|
||||
QMap<QString,PropertyContentInfo> _mapPro;
|
||||
QFormLayout* createFormLayout(QWidget* parent);
|
||||
|
|
|
|||
|
|
@ -24,9 +24,11 @@ public:
|
|||
virtual void createGroupView(GroupStateInfo);
|
||||
virtual QMap<QString,PropertyStateInfo> getPropertyValue(BaseProperty* = nullptr); //返回当前页面的属性值
|
||||
virtual void setPropertyValue(QVariant);
|
||||
virtual void clearData();
|
||||
public slots:
|
||||
void onAddClicked();
|
||||
void onTableCustomContextMenuRequested(const QPoint &pos);
|
||||
void onTableCellChanged(int row, int column);
|
||||
protected:
|
||||
void addTableRow(QString sRatioRange,QString sAccuracy,QString sVolume,double dRatio,bool bPolarity,int index = -1);
|
||||
private:
|
||||
|
|
@ -39,6 +41,7 @@ private:
|
|||
QButtonGroup* _stateGroup_ct;
|
||||
int _count;
|
||||
QStringList _curLabels;
|
||||
bool m_bUpdating = false; // ✅ 防递归标志位
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -24,9 +24,11 @@ public:
|
|||
virtual void createGroupView(GroupStateInfo);
|
||||
virtual QMap<QString,PropertyStateInfo> getPropertyValue(BaseProperty* = nullptr); //返回当前页面的属性值
|
||||
virtual void setPropertyValue(QVariant);
|
||||
virtual void clearData();
|
||||
public slots:
|
||||
void onAddClicked();
|
||||
void onTableCustomContextMenuRequested(const QPoint &pos);
|
||||
void onTableCellChanged(int row, int column);
|
||||
protected:
|
||||
void addTableRow(QString sRatioRange,QString sAccuracy,QString sVolume,QString sStar,double dRatio,bool bPolarity,int index = -1);
|
||||
private:
|
||||
|
|
@ -36,6 +38,7 @@ private:
|
|||
QMap<QString,PtExtraInfo> _mapPT;
|
||||
QButtonGroup* _stateGroup_pt;
|
||||
int _count;
|
||||
bool m_bUpdating = false; // ✅ 防递归标志位
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -28,3 +28,41 @@ QFormLayout* BaseContentDlg::createFormLayout(QWidget* parent)
|
|||
layout->setContentsMargins(12, 12, 12, 12); // 内边距
|
||||
return layout;
|
||||
}
|
||||
|
||||
QJsonObject BaseContentDlg::parseCTWindingDefaultValue(const QVariant &value)
|
||||
{
|
||||
// 情况 1:已经是 QJsonObject ✅
|
||||
if (value.canConvert<QJsonObject>())
|
||||
{
|
||||
return value.value<QJsonObject>();
|
||||
}
|
||||
|
||||
// 情况 2:QVariantMap(Qt 常见中间态)
|
||||
if (value.canConvert<QVariantMap>())
|
||||
{
|
||||
return QJsonObject::fromVariantMap(value.toMap());
|
||||
}
|
||||
|
||||
// 情况 3:数据库来的 QString(JSON 文本)
|
||||
if (value.typeId() == QMetaType::QString)
|
||||
{
|
||||
QString jsonStr = value.toString().trimmed();
|
||||
if (jsonStr.isEmpty())
|
||||
return {};
|
||||
|
||||
QJsonParseError err;
|
||||
QJsonDocument doc = QJsonDocument::fromJson(jsonStr.toUtf8(), &err);
|
||||
if (err.error != QJsonParseError::NoError)
|
||||
{
|
||||
qWarning() << "CTWinding JSON parse error:" << err.errorString();
|
||||
return {};
|
||||
}
|
||||
|
||||
return doc.object();
|
||||
}
|
||||
|
||||
// 其他情况
|
||||
qWarning() << "Unsupported CTWinding defaultValue type:"
|
||||
<< value.typeName();
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,10 @@ CtExtraInfoDlg::CtExtraInfoDlg(QWidget *parent)
|
|||
|
||||
ui->tb_ct->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(ui->tb_ct, &QTableWidget::customContextMenuRequested, this, &CtExtraInfoDlg::onTableCustomContextMenuRequested);
|
||||
connect(ui->tb_ct,
|
||||
&QTableWidget::cellChanged,
|
||||
this,
|
||||
&CtExtraInfoDlg::onTableCellChanged);
|
||||
}
|
||||
|
||||
CtExtraInfoDlg::~CtExtraInfoDlg()
|
||||
|
|
@ -30,6 +34,22 @@ CtExtraInfoDlg::~CtExtraInfoDlg()
|
|||
delete ui;
|
||||
}
|
||||
|
||||
void CtExtraInfoDlg::clearData()
|
||||
{
|
||||
ui->le_ratedCurrent->clear();
|
||||
ui->le_pfwv_ct->clear();
|
||||
ui->le_iwv_ct->clear();
|
||||
ui->le_dsc_ct->clear();
|
||||
ui->le_isf->setText(0);
|
||||
ui->le_sttc->clear();
|
||||
ui->le_rf_ct->clear();
|
||||
ui->rb_zst_ct->setChecked(true);
|
||||
ui->tb_ct->clearContents();
|
||||
ui->tb_ct->setRowCount(0);
|
||||
_mapCT.clear();
|
||||
updateLables();
|
||||
}
|
||||
|
||||
void CtExtraInfoDlg::createGroupView(GroupStateInfo infos)
|
||||
{
|
||||
for(auto& info:infos.info) {
|
||||
|
|
@ -112,6 +132,7 @@ QMap<QString,PropertyStateInfo> CtExtraInfoDlg::getPropertyValue(BaseProperty* p
|
|||
|
||||
void CtExtraInfoDlg::setPropertyValue(QVariant var)
|
||||
{
|
||||
clearData();
|
||||
QMap<QString,PropertyStateInfo> map = var.value<QMap<QString,PropertyStateInfo>>();
|
||||
for(auto &info:map)
|
||||
{
|
||||
|
|
@ -154,23 +175,23 @@ void CtExtraInfoDlg::setPropertyValue(QVariant var)
|
|||
}
|
||||
else if(info.name == "CT绕组" || info.tagName == "ct_winding")
|
||||
{
|
||||
QString jsonString = info.defaultValue.toString();
|
||||
QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonString.toUtf8().data());
|
||||
QJsonObject jsonObject = jsonDocument.object();
|
||||
QJsonObject root = parseCTWindingDefaultValue(info.defaultValue);
|
||||
if (root.isEmpty())
|
||||
return;
|
||||
|
||||
QJsonObject object = jsonObject;
|
||||
QJsonArray arr = object["winding"].toArray();
|
||||
for (QJsonValueRef jsonObj : arr)
|
||||
QJsonArray arr = root.value("winding").toArray();
|
||||
for (const QJsonValue &v : arr)
|
||||
{
|
||||
QJsonObject node = jsonObj.toObject();
|
||||
int index = node["index"].toInt();
|
||||
QString sRatioRange = node["scope"].toString();
|
||||
QString sAccuracy = node["accuracy"].toString();
|
||||
QString sVolume = node["volume"].toString();
|
||||
double dRatio = node["ratio"].toDouble();
|
||||
bool bPolarity = node["polarity"].toBool();
|
||||
QJsonObject node = v.toObject();
|
||||
|
||||
addTableRow(sRatioRange,sAccuracy,sVolume,dRatio,bPolarity,index);
|
||||
int index = node.value("index").toInt();
|
||||
QString scope = node.value("scope").toString();
|
||||
QString accuracy= node.value("accuracy").toString();
|
||||
QString volume = node.value("volume").toString();
|
||||
double ratio = node.value("ratio").toDouble();
|
||||
bool polarity = node.value("polarity").toBool();
|
||||
|
||||
addTableRow(scope, accuracy, volume, ratio, polarity, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -209,53 +230,36 @@ void CtExtraInfoDlg::onTableCustomContextMenuRequested(const QPoint &pos) {
|
|||
|
||||
menu.exec(ui->tb_ct->viewport()->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
void CtExtraInfoDlg::onTableCellChanged(int row, int column)
|
||||
{
|
||||
if (m_bUpdating)
|
||||
return;
|
||||
|
||||
auto* idItem = ui->tb_ct->item(row, 0);
|
||||
if (!idItem)
|
||||
return;
|
||||
|
||||
int index = idItem->data(Qt::UserRole).toInt();
|
||||
QString key = QString::number(index);
|
||||
|
||||
if (!_mapCT.contains(key))
|
||||
return;
|
||||
|
||||
CtExtraInfo& info = _mapCT[key];
|
||||
|
||||
// ✅ 从 UI 回写到数据结构
|
||||
info.scope = ui->tb_ct->item(row, 1)->text();
|
||||
info.accuracy = ui->tb_ct->item(row, 2)->text();
|
||||
info.volume = ui->tb_ct->item(row, 3)->text();
|
||||
info.ratio = ui->tb_ct->item(row, 4)->text().toDouble();
|
||||
info.polarity = (ui->tb_ct->item(row, 5)->text().toInt() > 0) ? 1 : -1;
|
||||
|
||||
updateLables();
|
||||
}
|
||||
|
||||
void CtExtraInfoDlg::addTableRow(QString sRatioRange,QString sAccuracy,QString sVolume,double dRatio,bool bPolarity,int index)
|
||||
{
|
||||
/*if(_mapCT.contains(QString::number(index)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CtExtraInfo info;
|
||||
if(index == -1){ //缺省id时新建,否则加载
|
||||
info.index = _count;
|
||||
_count += 1;
|
||||
}
|
||||
else{
|
||||
info.index = index;
|
||||
}
|
||||
|
||||
int row = ui->tb_ct->rowCount();
|
||||
ui->tb_ct->insertRow(row);
|
||||
|
||||
//index
|
||||
QTableWidgetItem *item = new QTableWidgetItem(QString::number(info.index));
|
||||
item->setData(Qt::UserRole,info.index);
|
||||
ui->tb_ct->setItem(row, 0, item);
|
||||
|
||||
//变比范围
|
||||
ui->tb_ct->setItem(row, 1, new QTableWidgetItem(sRatioRange));
|
||||
|
||||
//精度等级
|
||||
ui->tb_ct->setItem(row, 2, new QTableWidgetItem(sAccuracy));
|
||||
|
||||
//二次负载容量
|
||||
ui->tb_ct->setItem(row, 3, new QTableWidgetItem(sVolume));
|
||||
|
||||
//变比
|
||||
ui->tb_ct->setItem(row, 4, new QTableWidgetItem(QString::number(dRatio)));
|
||||
|
||||
//极性
|
||||
ui->tb_ct->setItem(row, 5, new QTableWidgetItem(QString::number(bPolarity? 1 : -1)));
|
||||
|
||||
info.scope = sRatioRange;
|
||||
info.accuracy = sAccuracy;
|
||||
info.volume = sVolume;
|
||||
info.ratio = dRatio;
|
||||
info.polarity = bPolarity? 1 : -1;
|
||||
_mapCT.insert(QString::number(info.index),info);
|
||||
|
||||
updateLables();*/
|
||||
if (index != -1) {
|
||||
if (_mapCT.contains(QString::number(index)))
|
||||
return;
|
||||
|
|
@ -275,6 +279,8 @@ void CtExtraInfoDlg::addTableRow(QString sRatioRange,QString sAccuracy,QString s
|
|||
info.ratio = dRatio;
|
||||
info.polarity = bPolarity ? 1 : -1;
|
||||
|
||||
m_bUpdating = true; // ✅ 防止触发 cellChanged
|
||||
|
||||
// 表格显示
|
||||
auto* idItem = new QTableWidgetItem(QString::number(newIndex));
|
||||
idItem->setData(Qt::UserRole, newIndex);
|
||||
|
|
@ -286,6 +292,7 @@ void CtExtraInfoDlg::addTableRow(QString sRatioRange,QString sAccuracy,QString s
|
|||
ui->tb_ct->setItem(row, 4, new QTableWidgetItem(QString::number(dRatio)));
|
||||
ui->tb_ct->setItem(row, 5, new QTableWidgetItem(QString::number(info.polarity)));
|
||||
|
||||
m_bUpdating = false; // ✅ 恢复
|
||||
// map 同步
|
||||
_mapCT.insert(QString::number(newIndex), info);
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,10 @@ PtExtraInfoDlg::PtExtraInfoDlg(QWidget *parent)
|
|||
|
||||
ui->tb_pt->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(ui->tb_pt, &QTableWidget::customContextMenuRequested, this, &PtExtraInfoDlg::onTableCustomContextMenuRequested);
|
||||
connect(ui->tb_pt,
|
||||
&QTableWidget::cellChanged,
|
||||
this,
|
||||
&PtExtraInfoDlg::onTableCellChanged);
|
||||
}
|
||||
|
||||
PtExtraInfoDlg::~PtExtraInfoDlg()
|
||||
|
|
@ -29,6 +33,21 @@ PtExtraInfoDlg::~PtExtraInfoDlg()
|
|||
delete ui;
|
||||
}
|
||||
|
||||
void PtExtraInfoDlg::clearData()
|
||||
{
|
||||
ui->le_ratedVol->clear();
|
||||
ui->le_pfwv_pt->clear();
|
||||
ui->le_iwv_pt->clear();
|
||||
ui->le_ratedVolFactor->clear();
|
||||
ui->le_pwwgm->setText(0);
|
||||
ui->le_rf_pt->clear();
|
||||
ui->rb_tpt_pt->setChecked(true);
|
||||
|
||||
ui->tb_pt->clearContents();
|
||||
ui->tb_pt->setRowCount(0);
|
||||
_mapPT.clear();
|
||||
}
|
||||
|
||||
void PtExtraInfoDlg::createGroupView(GroupStateInfo infos)
|
||||
{
|
||||
for(auto& info:infos.info) {
|
||||
|
|
@ -108,6 +127,7 @@ QMap<QString,PropertyStateInfo> PtExtraInfoDlg::getPropertyValue(BaseProperty* p
|
|||
|
||||
void PtExtraInfoDlg::setPropertyValue(QVariant var)
|
||||
{
|
||||
clearData();
|
||||
QMap<QString,PropertyStateInfo> map = var.value<QMap<QString,PropertyStateInfo>>();
|
||||
for(auto &info:map)
|
||||
{
|
||||
|
|
@ -147,13 +167,11 @@ void PtExtraInfoDlg::setPropertyValue(QVariant var)
|
|||
}
|
||||
else if(info.name == "PT二次绕组" || info.tagName == "pt_sec_winding")
|
||||
{
|
||||
QString jsonString = info.defaultValue.toString();
|
||||
QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonString.toUtf8().data());
|
||||
QJsonObject jsonObject = jsonDocument.object();
|
||||
QJsonObject root = parseCTWindingDefaultValue(info.defaultValue);
|
||||
if (root.isEmpty())
|
||||
return;
|
||||
|
||||
QJsonObject object = jsonObject;
|
||||
|
||||
QJsonArray arr = object["winding"].toArray();
|
||||
QJsonArray arr = root.value("winding").toArray();
|
||||
for (QJsonValueRef jsonObj : arr)
|
||||
{
|
||||
QJsonObject node = jsonObj.toObject();
|
||||
|
|
@ -206,55 +224,35 @@ void PtExtraInfoDlg::onTableCustomContextMenuRequested(const QPoint &pos) {
|
|||
menu.exec(ui->tb_pt->viewport()->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
void PtExtraInfoDlg::onTableCellChanged(int row, int column)
|
||||
{
|
||||
Q_UNUSED(column);
|
||||
|
||||
if (m_bUpdating)
|
||||
return;
|
||||
|
||||
auto* idItem = ui->tb_pt->item(row, 0);
|
||||
if (!idItem)
|
||||
return;
|
||||
|
||||
int index = idItem->data(Qt::UserRole).toInt();
|
||||
QString key = QString::number(index);
|
||||
|
||||
if (!_mapPT.contains(key))
|
||||
return;
|
||||
|
||||
PtExtraInfo& info = _mapPT[key];
|
||||
|
||||
info.scope = ui->tb_pt->item(row, 1)->text();
|
||||
info.accuracy = ui->tb_pt->item(row, 2)->text();
|
||||
info.volume = ui->tb_pt->item(row, 3)->text();
|
||||
info.ratio = ui->tb_pt->item(row, 4)->text().toDouble();
|
||||
info.polarity = (ui->tb_pt->item(row, 5)->text().toInt() > 0) ? 1 : -1;
|
||||
info.star = ui->tb_pt->item(row, 6)->text();
|
||||
}
|
||||
|
||||
void PtExtraInfoDlg::addTableRow(QString sRatioRange,QString sAccuracy,QString sVolume,QString sStar,double dRatio,bool bPolarity,int index)
|
||||
{
|
||||
/*if(_mapPT.contains(QString::number(index)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PtExtraInfo info;
|
||||
if(index == -1){ //缺省id时新建,否则加载
|
||||
info.index = _count;
|
||||
_count += 1;
|
||||
}
|
||||
else{
|
||||
info.index = index;
|
||||
}
|
||||
|
||||
int row = ui->tb_pt->rowCount();
|
||||
ui->tb_pt->insertRow(row);
|
||||
|
||||
// index
|
||||
QTableWidgetItem *item = new QTableWidgetItem(QString::number(info.index));
|
||||
item->setData(Qt::UserRole,info.index);
|
||||
ui->tb_pt->setItem(row, 0, item);
|
||||
|
||||
//变比范围
|
||||
ui->tb_pt->setItem(row, 1, new QTableWidgetItem(sRatioRange));
|
||||
|
||||
//精度等级
|
||||
ui->tb_pt->setItem(row, 2, new QTableWidgetItem(sAccuracy));
|
||||
|
||||
//二次负载容量
|
||||
ui->tb_pt->setItem(row, 3, new QTableWidgetItem(sVolume));
|
||||
|
||||
// 变比
|
||||
ui->tb_pt->setItem(row, 4, new QTableWidgetItem(QString::number(dRatio)));
|
||||
|
||||
// 极性
|
||||
ui->tb_pt->setItem(row, 5, new QTableWidgetItem(QString::number(bPolarity? 1 : -1)));
|
||||
|
||||
//接线
|
||||
ui->tb_pt->setItem(row, 6, new QTableWidgetItem(sStar));
|
||||
|
||||
info.scope = sRatioRange;
|
||||
info.accuracy = sAccuracy;
|
||||
info.volume = sVolume;
|
||||
info.star = sStar;
|
||||
info.ratio = dRatio;
|
||||
info.polarity = bPolarity? 1 : -1;
|
||||
_mapPT.insert(QString::number(info.index),info);*/
|
||||
if (index != -1) {
|
||||
if (_mapPT.contains(QString::number(index)))
|
||||
return;
|
||||
|
|
@ -274,6 +272,8 @@ void PtExtraInfoDlg::addTableRow(QString sRatioRange,QString sAccuracy,QString s
|
|||
info.ratio = dRatio;
|
||||
info.polarity = bPolarity ? 1 : -1;
|
||||
|
||||
m_bUpdating = true; // ✅ 防止触发 cellChanged
|
||||
|
||||
// index 列
|
||||
auto* idItem = new QTableWidgetItem(QString::number(newIndex));
|
||||
idItem->setData(Qt::UserRole, newIndex);
|
||||
|
|
@ -286,27 +286,12 @@ void PtExtraInfoDlg::addTableRow(QString sRatioRange,QString sAccuracy,QString s
|
|||
ui->tb_pt->setItem(row, 5, new QTableWidgetItem(QString::number(info.polarity)));
|
||||
ui->tb_pt->setItem(row, 6, new QTableWidgetItem(sStar));
|
||||
|
||||
m_bUpdating = false; // ✅ 恢复
|
||||
|
||||
_mapPT.insert(QString::number(newIndex), info);
|
||||
}
|
||||
|
||||
void PtExtraInfoDlg::deleteRowWithReindex(int row) {
|
||||
// 1. 获取要删除的ID
|
||||
/*QTableWidgetItem* pFirstItem = ui->tb_pt->item(row, 0);
|
||||
if (!pFirstItem) return;
|
||||
|
||||
int deletedId = pFirstItem->data(Qt::UserRole).toInt();
|
||||
QString deletedKey = QString::number(deletedId);
|
||||
|
||||
// 2. 从表格中删除行
|
||||
ui->tb_pt->removeRow(row);
|
||||
|
||||
// 3. 从_mapCT中删除对应项
|
||||
if (_mapPT.contains(deletedKey)) {
|
||||
_mapPT.remove(deletedKey);
|
||||
}
|
||||
|
||||
// 4. 重新排序和更新index
|
||||
reorderMapAndUpdateIndices(row);*/
|
||||
if (row < 0 || row >= ui->tb_pt->rowCount())
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -34,74 +34,6 @@
|
|||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>21</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>21</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QWidget {
|
||||
background: #2c5282;
|
||||
color: white;
|
||||
border: none;
|
||||
}
|
||||
|
||||
QWidget QLabel {
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
background: transparent;
|
||||
}</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>-1</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>工程模图标设置</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableWidget" name="tableWidget"/>
|
||||
</item>
|
||||
|
|
|
|||
Loading…
Reference in New Issue