PowerModeler/source/modelInfoEditDialog.cpp

415 lines
14 KiB
C++
Raw Normal View History

2025-03-14 16:06:20 +08:00
#include "modelInfoEditDialog.h"
#include "./ui_modelInfoEditDialog.h"
2025-04-21 14:29:20 +08:00
#include "maskLayer.h"
2025-03-14 16:06:20 +08:00
#include "mainwindow.h"
#include "sqlQueryExecutor.h"
2025-04-18 18:44:26 +08:00
#include "textColorPreserveDelegate.h"
#include "customBorderContainer.h"
2025-03-14 16:06:20 +08:00
#include <QRegularExpressionValidator>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QFileDialog>
#include <QSvgRenderer>
#include <QPainter>
2025-03-14 16:06:20 +08:00
#define itemRole_groupID 1
#define itemRole_isPublic 2
ModelInfoEditDialog::ModelInfoEditDialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::ModelInfoEditDialog)
, m_pMainWindow(nullptr)
2025-04-18 18:44:26 +08:00
, m_curModelID(-1)
2025-03-14 16:06:20 +08:00
{
ui->setupUi(this);
2025-04-03 16:48:21 +08:00
if(QSysInfo::kernelType() == "linux")
{
2025-04-03 18:01:23 +08:00
//Linux下默认的Qt::Dialog即使有父窗口也无法按照子窗口的行为进行展示并且最大、最小按钮不好关闭因此需要去掉Dialog属性随之而来的问题是模态无法起作用
setWindowFlags(windowFlags() & ~Qt::Dialog);
2025-04-03 16:48:21 +08:00
setStyleSheet("QDialog{border: 1px solid rgb(205,205,205);border-radius:5px;background-color:rgb(250,250,250);}");
2025-04-18 18:44:26 +08:00
m_customBorderContainer = new CustomBorderContainer(this);
m_customBorderContainer->setOperationOptions(CustomBorderContainer::Movable | CustomBorderContainer::Resizable);
2025-04-03 16:48:21 +08:00
}
2025-03-14 16:06:20 +08:00
initialize();
}
ModelInfoEditDialog::~ModelInfoEditDialog()
{
delete ui;
}
void ModelInfoEditDialog::showEvent(QShowEvent* e)
{
refreshGroupList();
refreshComponentTypeList();
2025-03-14 16:06:20 +08:00
if(m_state == DS_New)
{
resetUI();
setWindowIcon(QIcon(":/img/images/icon_addTable.png"));
setWindowTitle(QString::fromWCharArray(L"新建模型"));
2025-03-14 16:06:20 +08:00
}
else //获取指定Model信息
{
setWindowIcon(QIcon(":/img/images/icon_editTable.png"));
setWindowTitle(QString::fromWCharArray(L"修改模型"));
ui->tabWidget->setCurrentIndex(0);
if(m_pMainWindow)
{
QString connection = m_pMainWindow->getCurConnection();
Model model = SqlQueryExecutor::instance().getModelInfo(connection, m_curModelID);
ui->lineEdit_modelName->setText(model.name);
ui->lineEdit_modelType->setText(model.type);
QString componentName = SqlQueryExecutor::instance().getComponentName(connection, model.grahicElement);
ui->grahpicElement->setCurrentText(componentName);
ui->plainTextEdit_modelComment->setPlainText(model.remark);
QSvgRenderer renderer(model.icon);
if(renderer.isValid())
{
previewSVG(renderer);
ui->lineEdit_modelImage->setText("from db");
}
else
{
ui->lineEdit_modelImage->setText("");
ui->modelImagePreview->setPixmap(QPixmap(":/img/images/icon_file.png"));
}
for(int groupID : model.groups)
{
AttributeGroup group = SqlQueryExecutor::instance().getAttributeGroupData(connection, groupID);
if(group.name.isEmpty())
continue;
if(group.isPublic)
continue;
2025-03-14 16:06:20 +08:00
QListWidgetItem* item = new QListWidgetItem(group.name);
item->setFlags(item->flags() & ~Qt::ItemIsEditable);
item->setData(Qt::UserRole + itemRole_groupID, group.id);
item->setData(Qt::UserRole + itemRole_isPublic, group.isPublic);
ui->selectedList->addItem(item);
}
m_oldName = model.name;
m_oldType = model.type;
m_oldIconData = model.icon;
m_oldGroups = model.groups;
}
else
{
resetUI();
setErrorInfo(QString::fromWCharArray(L"获取模型信息失败"));
}
2025-03-14 16:06:20 +08:00
}
QDialog::showEvent(e);
2025-03-14 16:06:20 +08:00
}
void ModelInfoEditDialog::initialize()
{
m_state = DS_New;
m_curModelID = -1;
ui->btnAddGroup->setVisible(false);
2025-04-21 14:29:20 +08:00
m_pMaskLayer = new MaskLayer(this);
//正则表达式,只能输入字母
QRegularExpression regExp("[A-Za-z0-9_]+");
2025-03-14 16:06:20 +08:00
QRegularExpressionValidator* validator = new QRegularExpressionValidator(regExp, this);
ui->lineEdit_modelType->setValidator(validator);
2025-04-18 18:44:26 +08:00
TextColorPreserveDelegate* delegate = new TextColorPreserveDelegate(this);
ui->sourceList->setItemDelegate(delegate);
ui->selectedList->setItemDelegate(delegate);
connect(ui->btnSelectImage, &QPushButton::clicked, this, &ModelInfoEditDialog::onBtnClicked_selectImage);
2025-03-14 16:06:20 +08:00
connect(ui->btnSave, &QPushButton::clicked, this, &ModelInfoEditDialog::onBtnClicked_save);
connect(ui->btnCancle, &QPushButton::clicked, this, &ModelInfoEditDialog::onBtnClicked_cancle);
connect(ui->btnAddGroup, &QPushButton::clicked, this, &ModelInfoEditDialog::onBtnClicked_addGroup);
connect(ui->btnRemoveSelected, &QPushButton::clicked, this, &ModelInfoEditDialog::onBtnClicked_removeSelected);
connect(ui->sourceList, &QListWidget::itemDoubleClicked, this, &ModelInfoEditDialog::onItemDblCliked_sourceList);
}
void ModelInfoEditDialog::resetUI()
{
ui->tabWidget->setCurrentIndex(0);
ui->lineEdit_modelName->setText("");
ui->lineEdit_modelType->setText("");
ui->lineEdit_modelImage->setText("");
2025-03-14 16:06:20 +08:00
ui->plainTextEdit_modelComment->setPlainText("");
ui->label_error->clear();
ui->modelImagePreview->setPixmap(QPixmap(":/img/images/icon_file.png"));
m_oldName = "";
m_oldType = "";
2025-03-14 16:06:20 +08:00
}
void ModelInfoEditDialog::refreshGroupList()
{
if(m_pMainWindow)
{
ui->sourceList->clear();
ui->selectedList->clear();
2025-04-18 18:44:26 +08:00
2025-03-14 16:06:20 +08:00
QString connection = m_pMainWindow->getCurConnection();
const QVector<AttributeGroup> groups = SqlQueryExecutor::instance().getAttributeGroup(connection);
for(const AttributeGroup& group : groups)
{
QListWidgetItem* sourceItem = new QListWidgetItem(group.name);
sourceItem->setFlags(sourceItem->flags() & ~Qt::ItemIsEditable);
sourceItem->setData(Qt::UserRole + itemRole_groupID, group.id);
sourceItem->setData(Qt::UserRole + itemRole_isPublic, group.isPublic);
ui->sourceList->addItem(sourceItem);
if(group.isPublic)
{
QListWidgetItem* selectedItem = new QListWidgetItem(*sourceItem);
//selectedItem->setIcon(QIcon(":/img/images/icon_no.png"));
selectedItem->setForeground(QBrush(QColor(128,128,128)));
ui->selectedList->addItem(selectedItem);
}
}
}
}
void ModelInfoEditDialog::refreshComponentTypeList()
{
if(m_pMainWindow)
{
ui->grahpicElement->clear();
ui->grahpicElement->addItem(QString::fromWCharArray(L"未选择"), -1);
QString connection = m_pMainWindow->getCurConnection();
const QVector<Component> components = SqlQueryExecutor::instance().getComponents(connection);
for(const Component& component : components)
ui->grahpicElement->addItem(component.name, component.id);
}
}
2025-03-14 16:06:20 +08:00
void ModelInfoEditDialog::setErrorInfo(const QString& info)
{
if(m_pMainWindow)
m_pMainWindow->showMessageDialog(type_warning, QString::fromWCharArray(L"错误"),info);
else
ui->label_error->setText(info);
}
void ModelInfoEditDialog::setMainWindow(MainWindow* window)
{
m_pMainWindow = window;
}
void ModelInfoEditDialog::setState(DialogState state)
{
m_state = state;
if(state == DS_New)
m_curModelID = -1;
}
2025-04-18 18:44:26 +08:00
void ModelInfoEditDialog::setModel(int id)
{
m_curModelID = id;
m_state = DS_Edit;
2025-04-18 18:44:26 +08:00
}
2025-04-21 14:29:20 +08:00
void ModelInfoEditDialog::showMask()
{
m_pMaskLayer->setGeometry(0, 0, this->width(), this->height());
m_pMaskLayer->show();
}
void ModelInfoEditDialog::hideMask()
{
m_pMaskLayer->close();
}
void ModelInfoEditDialog::previewSVG(QSvgRenderer& renderer)
{
//计算DPI缩放银子
qreal dipScale = qApp->devicePixelRatio();
QSize scaledSize = ui->modelImagePreview->size() * dipScale;
//创建透明背景的高分辨率图像
QImage image(scaledSize, QImage::Format_A2BGR30_Premultiplied);
image.fill(Qt::transparent);
//高质量渲染设置
QPainter painter(&image);
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing);
//渲染到目标对象
renderer.render(&painter, QRect(0, 0, scaledSize.width(), scaledSize.height()));
//转换为像素图
QPixmap pixmap = QPixmap::fromImage(image);
pixmap.setDevicePixelRatio(dipScale);
//显示图片
ui->modelImagePreview->clear();
ui->modelImagePreview->setPixmap(pixmap);
}
2025-03-14 16:06:20 +08:00
void ModelInfoEditDialog::onItemDblCliked_sourceList(QListWidgetItem* item)
{
if(item->data(Qt::UserRole + itemRole_isPublic).toBool())
return;
QList<QListWidgetItem*> foundItems = ui->selectedList->findItems(item->text(), Qt::MatchFixedString);
if(foundItems.isEmpty())
{
QListWidgetItem* selectedItem = new QListWidgetItem(*item);
ui->selectedList->addItem(selectedItem);
}
}
void ModelInfoEditDialog::onBtnClicked_selectImage()
{
QString filePath = QFileDialog::getOpenFileName(this,
"选择SVG文件",
QDir::homePath(),
"SVG Files (*.svg)");
if(filePath.isEmpty())
return;
//加载图片(适配高DPI)
QSvgRenderer renderer(filePath);
if(renderer.isValid())
{
//显示图片
previewSVG(renderer);
//显示图片路径
ui->lineEdit_modelImage->setText(filePath);
}
else if(m_pMainWindow)
m_pMainWindow->showMessageDialog(type_warning, QString::fromWCharArray(L"错误"),QString::fromWCharArray(L"SVG文件加载失败"));
}
2025-03-14 16:06:20 +08:00
void ModelInfoEditDialog::onBtnClicked_save()
{
if(ui->lineEdit_modelName->text() == "" || ui->lineEdit_modelType->text() == "" || ui->lineEdit_modelImage->text() == ""
|| (ui->grahpicElement->count() > 1 && ui->grahpicElement->currentIndex() == 0))
2025-03-14 16:06:20 +08:00
{
setErrorInfo(QString::fromWCharArray(L"除‘备注’外不能有信息为空"));
return;
}
QString modelName = ui->lineEdit_modelName->text();
QString modeType = ui->lineEdit_modelType->text();
QString remark = ui->plainTextEdit_modelComment->toPlainText();
QVector<int> groups;
for(int i = 0; i < ui->selectedList->count(); i++)
{
QListWidgetItem* item = ui->selectedList->item(i);
groups.append(item->data(Qt::UserRole + itemRole_groupID).toInt());
}
if(!m_pMainWindow)
{
setErrorInfo(QString::fromWCharArray(L"无法获取当前数据库链接"));
resetUI();
return;
}
//先判断是否存在同名
QString connection = m_pMainWindow->getCurConnection();
bool nameExists = SqlQueryExecutor::instance().modelNameExistsInDB(connection, modelName, m_oldName);
2025-03-14 16:06:20 +08:00
if(nameExists)
{
setErrorInfo(QString::fromWCharArray(L"已存同名的模型,请修改模型名称"));
ui->tabWidget->setCurrentIndex(0);
return;
}
else //然后判断类型是否存在相同
{
bool typeExists = SqlQueryExecutor::instance().modelTypeExistsInDB(connection, modeType, m_oldType);
2025-03-14 16:06:20 +08:00
if(typeExists)
{
setErrorInfo(QString::fromWCharArray(L"已存同类型的模型,请修改模型类型"));
ui->tabWidget->setCurrentIndex(0);
return;
}
}
2025-04-18 18:44:26 +08:00
QByteArray iconData;
QFile iconFile(ui->lineEdit_modelImage->text());
if(iconFile.exists())
{
if(iconFile.open(QIODevice::ReadOnly))
{
iconData = iconFile.readAll();
iconFile.close();
}
else
{
setErrorInfo(QString::fromWCharArray(L"所选图元文件无法读取,请检查或重新选择"));
return;
}
}
else
iconData = m_oldIconData;
int graphicElementID = ui->grahpicElement->currentData().toInt();
Model model(m_curModelID, modelName, modeType, remark, iconData, graphicElementID, groups);
bool result = false;
if(m_state == DS_New)
{
result = SqlQueryExecutor::instance().addModel(connection, model);
}
else
{
result = SqlQueryExecutor::instance().updateModelInfo(connection, model);
}
2025-03-14 16:06:20 +08:00
if(result)
{
if(m_state == DS_New)
2025-03-14 16:06:20 +08:00
{
emit addModel(model);
m_pMainWindow->showMessageDialog(type_question, QString::fromWCharArray(L"成功"),QString::fromWCharArray(L"信息存储完成,是否继续添加模型"));
if(g_msgDlgBtn == btn_No)
close();
else
{
resetUI();
refreshGroupList();
}
}
else if(m_state == DS_Edit)
{
if(modelName != m_oldName) //更新对应树节点
{
emit updateModelNodeText(m_curModelID, modelName);
}
//计算删除和添加的属性组-转化为QSet然后利用QSet的-’运算符操作
QSet<int> oldSet(m_oldGroups.begin(), m_oldGroups.end());
QSet<int> newSet(model.groups.begin(), model.groups.end());
QSet<int> added = newSet - oldSet;
QSet<int> removed = oldSet - newSet;
close();
2025-03-14 16:06:20 +08:00
}
}
else
setErrorInfo(QString::fromWCharArray(L"信息存储失败,详情可见日志文件"));
}
void ModelInfoEditDialog::onBtnClicked_cancle()
{
close();
}
void ModelInfoEditDialog::onBtnClicked_addGroup()
{
setErrorInfo(QString::fromWCharArray(L"该功能暂未开放"));
}
void ModelInfoEditDialog::onBtnClicked_removeSelected()
{
QListWidgetItem* item = ui->selectedList->currentItem();
if(item && item->data(Qt::UserRole + itemRole_isPublic).toBool())
{
setErrorInfo(QString::fromWCharArray(L"该组别为必选组别,不可移除"));
return;
}
int row = ui->selectedList->currentRow();
item = ui->selectedList->takeItem(row);
if(item)
delete item;
}