完善‘连接信息’动态修改逻辑

This commit is contained in:
duanshengchao 2025-05-30 18:51:23 +08:00
parent bb45a1a1ac
commit 668aef03c1
23 changed files with 645 additions and 215 deletions

View File

@ -12,6 +12,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Sql)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Svg)
#ui.h
set(CMAKE_AUTOUIC_SEARCH_PATHS "ui")
@ -127,7 +128,8 @@ target_include_directories(PowerModeler PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc
target_link_libraries(PowerModeler PRIVATE Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Sql)
Qt${QT_VERSION_MAJOR}::Sql
Qt${QT_VERSION_MAJOR}::Svg)
# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
# If you are developing for iOS or macOS you should consider setting an

View File

@ -1,164 +0,0 @@
cmake_minimum_required(VERSION 3.5)
project(PowerModeler VERSION 0.1 LANGUAGES CXX)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Sql)
#默认ui文件要和.h头文件在一个目录若不在一个目录需要指定其所在目录
set(CMAKE_AUTOUIC_SEARCH_PATHS "ui")
set(H_HEADER_FILES
include/global.h
include/logger.h
include/mainwindow.h
include/dbManager.h
include/dbBrowser.h
include/dbStructureNode.h
include/dbStructureModel.h
include/dbStructureView.h
include/connectionDialog.hgit
include/messageDialog.h
include/messageBox.h
include/settings.h
include/tableWidgetHoverDelegate.h
include/textColorPreserveDelegate.h
include/customMenu.h
include/multiLineHeaderView.h
include/modelInfoEditDialog.h
include/sqlQueryExecutor.h
include/attributeNamespace.h
include/attributeTableModel.h
include/attributeTableDelegate.h
include/attributeView.h
include/attributeSelector.h
include/maskLayer.h
include/maskManager.h
include/customBorderContainer.h
include/groupSelectionDialog.h
include/dataSyncManager.h
include/importExportManager.h
)
set(CPP_SOURCE_FILES
source/main.cpp
source/global.cpp
source/logger.cpp
source/mainwindow.cpp
source/dbManager.cpp
source/dbBrowser.cpp
source/dbStructureNode.cpp
source/dbStructureModel.cpp
source/dbStructureView.cpp
source/connectionDialog.cpp
source/messageDialog.cpp
source/messageBox.cpp
source/settings.cpp
source/tableWidgetHoverDelegate.cpp
source/textColorPreserveDelegate.cpp
source/customMenu.cpp
source/multiLineHeaderView.cpp
source/modelInfoEditDialog.cpp
source/sqlQueryExecutor.cpp
source/attributeTableModel.cpp
source/attributeTableDelegate.cpp
source/attributeView.cpp
source/attributeSelector.cpp
source/maskLayer.cpp
source/maskManager.cpp
source/customBorderContainer.cpp
source/groupSelectionDialog.cpp
source/dataSyncManager.cpp
source/importExportManager.cpp
)
set(UI_FILES
ui/mainwindow.ui
ui/dbBrowser.ui
ui/connectionDialog.ui
ui/messageDialog.ui
ui/modelInfoEditDialog.ui
ui/textEditWidget.ui
ui/attributeSelector.ui
ui/groupSelectionDialog.ui
)
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
qt_add_executable(PowerModeler
MANUAL_FINALIZATION
${H_HEADER_FILES}
${CPP_SOURCE_FILES}
${UI_FILES}
resource/PowerModeler.qrc
)
# Define target properties for Android with Qt 6 as:
# set_property(TARGET PowerModeler APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
# ${CMAKE_CURRENT_SOURCE_DIR}/android)
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
else()
if(ANDROID)
add_library(PowerModeler SHARED
${H_HEADER_FILES}
${CPP_SOURCE_FILES}
${UI_FILES}
resource/PowerModeler.qrc
)
# Define properties for Android with Qt 5 after find_package() calls as:
# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
else()
add_executable(PowerModeler
${H_HEADER_FILES}
${CPP_SOURCE_FILES}
${UI_FILES}
resource/PowerModeler.qrc
)
endif()
endif()
target_include_directories(PowerModeler PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(PowerModeler PRIVATE Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Sql)
# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
# If you are developing for iOS or macOS you should consider setting an
# explicit, fixed bundle identifier manually though.
if(${QT_VERSION} VERSION_LESS 6.1.0)
set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.PowerModeler)
endif()
set_target_properties(PowerModeler PROPERTIES
${BUNDLE_ID_OPTION}
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
)
include(GNUInstallDirs)
install(TARGETS PowerModeler
BUNDLE DESTINATION .
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
#配置文件
set(CONFIG_FILE "app_config.ini")
set(CONFIG_FILE_DIR "${CMAKE_BINARY_DIR}")
if(NOT EXISTS "${CONFIG_FILE_DIR}/${CONFIG_FILE}")
file(COPY app_config.ini DESTINATION "${CONFIG_FILE_DIR}")
else()
message(STATUS "${CONFIG_FILE} already exists, skipping copy")
endif()
if(QT_VERSION_MAJOR EQUAL 6)
qt_finalize_executable(PowerModeler)
endif()

View File

@ -25,6 +25,7 @@ public:
signals:
void errorOccurred(const QString& strConnectionName, const QString& error); //错误信息信号
void connectionStatusChanged(const QString& strConnectionName, bool bConnected);
void updateConnectionName(const QString& oldName, const QString& newName);
private:
QMap<QString, DatabaseConfig> m_configs;

View File

@ -23,6 +23,7 @@ public:
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
QVariant data(const QModelIndex& index, int role) const override;
bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
//业务功能接口

View File

@ -51,6 +51,7 @@ public:
//数据访问
NodeType type() const;
QString name() const;
void setName(const QString&);
QIcon icon() const;
void setStatus(NodeStatus);
NodeStatus status() const;

View File

@ -39,6 +39,7 @@ private:
signals:
void actionTrigger_addModel();
void acitonTrigger_updateModel(int);
void actionTrigger_addGroup(int);
void openAttributeInfo(const QString&, ModelAttributeGroup&);
void closeAttributeInfo(ModelAttributeGroup&);
@ -47,6 +48,7 @@ signals:
private slots:
void itemDoubleClick(const QModelIndex&);
void showContextMenu(const QPoint&);
void onSIG_updateConnectionName(const QString& oldName, const QString& newName);
};
#endif //DBSTRUCTUREVIEW_H

View File

@ -74,13 +74,17 @@ struct Model
QString name; //中文展示名称
QString type; //英文标识名称
QString remark;
QByteArray icon;
int grahicElement;
QVector<int> groups;
Model(int id, QString name, QString type, QString remark, QVector<int> groups)
Model(int id, QString name, QString type, QString remark, QByteArray icon, int grahicElement, QVector<int> groups)
: id(id),
name(std::move(name)),
type(std::move(type)),
remark(std::move(remark)),
icon(std::move(icon)),
grahicElement(std::move(grahicElement)),
groups(std::move(groups)){}
};
@ -138,6 +142,18 @@ struct PaginationInfo
int currentPage; //当前页数
};
struct Component
{
int id;
QString type;
QString name;
Component(int id, QString type, QString name)
: id(id),
type(std::move(type)),
name(std::move(name)){}
};
class DatabaseException : public std::runtime_error
{
public:

View File

@ -56,6 +56,7 @@ private slots:
void onActionTrigger_connect();
void onActionTrigger_disconnect();
void onActionTrigger_addModel();
void onActionTrigger_updateModel(int);
void onActionTrigger_removeModel();
void onActionTrigger_addGroup(int);

View File

@ -14,6 +14,7 @@ class MainWindow;
class MaskLayer;
class QListWidgetItem;
class CustomBorderContainer;
class QSvgRenderer;
class ModelInfoEditDialog : public QDialog
{
@ -23,7 +24,7 @@ public:
ModelInfoEditDialog(QWidget *parent = nullptr);
~ModelInfoEditDialog();
void setState(DialogState state) {m_state = state;}
void setState(DialogState state);
void setMainWindow(MainWindow*);
void setModel(int);
@ -38,12 +39,19 @@ private:
void setErrorInfo(const QString&);
void resetUI();
void refreshGroupList();
void refreshComponentTypeList();
void previewSVG(QSvgRenderer&);
Ui::ModelInfoEditDialog* ui;
DialogState m_state;
MaskLayer* m_pMaskLayer;
MainWindow* m_pMainWindow;
int m_curModelID;
//一些用来支撑修改信息时的变量
QString m_oldName;
QString m_oldType;
QByteArray m_oldIconData;
QVector<int> m_oldGroups;
CustomBorderContainer* m_customBorderContainer;
@ -51,6 +59,7 @@ signals:
void addModel(Model&);
public slots:
void onBtnClicked_selectImage();
void onBtnClicked_save();
void onBtnClicked_cancle();
void onBtnClicked_addGroup();

View File

@ -33,10 +33,12 @@ public:
const QVector<Model> getModels(const QString&);
int getModelCount(const QString&);
bool addModel(const QString&, Model&);
bool modelNameExistsInDB(const QString&, const QString&);
bool modelTypeExistsInDB(const QString&, const QString&);
bool updateModelInfo(const QString&, Model&);
Model getModelInfo(const QString&, int);
bool modelNameExistsInDB(const QString&, const QString&, const QString& skipCheckName = "");
bool modelTypeExistsInDB(const QString&, const QString&, const QString& skipCheckType = "");
bool removeModel(const QString&, int);
bool addModleGrpus(const QString&, int, QVector<int>);
bool addModleGroups(const QString&, int, QVector<int>);
QVector<int> getModelGroups(const QString&, int);
//属性相关
int getAttributeCount(const QString&, int, int, const QString& filterChars = "");
@ -47,6 +49,9 @@ public:
bool batchInsertAttributes(const QString&, int, int, QList<Attribute>);
bool batchDeleteAttributes(const QString&, int, int, QList<int>);
bool batchUpdateAttributes(const QString&, int, int, QList<Attribute>);
//其它
const QVector<Component> getComponents(const QString&);
const QString getComponentName(const QString&, int);
signals:
void errorOccurred(const QString& error);

View File

@ -1,5 +1,7 @@
<RCC>
<qresource prefix="img">
<file>images/icon_ellipsis.png</file>
<file>images/icon_file.png</file>
<file>images/icon_multiple-choice.png</file>
<file>images/icon_multiple-choice_disable.png</file>
<file>images/icon_hierarchy_unchecked.png</file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 B

View File

@ -145,7 +145,7 @@ void ConnectionDialog::addNewConnListItem()
{
int rowCount = ui->connectionList->rowCount();
ui->connectionList->insertRow(rowCount);
ui->connectionList->setItem(rowCount, 0, new QTableWidgetItem(QString::fromWCharArray(L"新建"))); //名称
ui->connectionList->setItem(rowCount, 0, new QTableWidgetItem(QString::fromWCharArray(L"新建"))); //名称
QTableWidgetItem* item = ui->connectionList->item(rowCount, 0);
item->setFlags(item->flags() & (~Qt::ItemIsEditable));
item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
@ -387,10 +387,16 @@ void ConnectionDialog::onBtnClicked_save()
}
QString connName = ui->lineEdit_connection->text();
for(int i = 0; i < ui->connectionList->rowCount() - 1; i++) //和已保存的链接对比
if(connName == QString::fromWCharArray(L"新建连接") || connName == QString::fromWCharArray(L"新建链接"))
{
setErrorInfo(QString::fromWCharArray(L"该链接名不可用"));
return;
}
for(int i = 0; i < ui->connectionList->rowCount(); i++)
{
QTableWidgetItem* item = ui->connectionList->item(i, 0);
if(item->text() == connName)
if(item->text() == connName && i != ui->connectionList->currentRow())
{
setErrorInfo(QString::fromWCharArray(L"已存在同名链接"));
return;

View File

@ -63,8 +63,29 @@ void DatabaseManager::removeDatabase(const QString& strConnectionName)
}
void DatabaseManager::updataDatabase(const DatabaseConfig& config)
{
if(m_configs.contains(config.strConnectionName))
// if(m_configs.contains(config.strConnectionName))
// m_configs[config.strConnectionName] = config;
bool isExist = false;
QString strConnectionName;
for(auto i = m_configs.begin(); i != m_configs.end(); ++i)
{
if(i.value().strID == config.strID)
{
isExist = true;
strConnectionName = i.key();
break;
}
}
if(isExist)
{
//通过先删除之前存储的信息再添加新的信息完成信息刷新
if(strConnectionName != config.strConnectionName)
{
m_configs.remove(strConnectionName);
emit updateConnectionName(strConnectionName, config.strConnectionName);
}
m_configs[config.strConnectionName] = config;
}
}
bool DatabaseManager::connect(const QString& strConnectionName)

View File

@ -103,6 +103,7 @@ QVariant DBStructureModel::data(const QModelIndex& index, int role) const
switch (role)
{
case Qt::DisplayRole:
case Qt::EditRole:
return node->columnData(DBStructureNode::ColumnName);
case Qt::DecorationRole:
return node->icon();
@ -111,6 +112,17 @@ QVariant DBStructureModel::data(const QModelIndex& index, int role) const
}
}
bool DBStructureModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
if (role != Qt::EditRole)
return false;
DBStructureNode* node = static_cast<DBStructureNode*>(index.internalPointer());
node->setName(value.toString());
emit dataChanged(index, index, {role});
return true;
}
QVariant DBStructureModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if(orientation == Qt::Horizontal && role == Qt::DisplayRole)

View File

@ -104,6 +104,11 @@ QString DBStructureNode::name() const
return m_name;
}
void DBStructureNode::setName(const QString& name)
{
m_name = name;
}
QIcon DBStructureNode::icon() const
{
return m_icon;

View File

@ -19,6 +19,7 @@ DBStructureView::DBStructureView(DatabaseManager* dbManager, QWidget* parent)
// });
m_curConnection = "";
connect(m_dbManager, &DatabaseManager::updateConnectionName, this, &DBStructureView::onSIG_updateConnectionName);
initView();
}
@ -308,6 +309,9 @@ void DBStructureView::showContextMenu(const QPoint& pos)
});
menu.addAction(QString::fromWCharArray(L"刷新"), []{});
menu.addSeparator();
menu.addAction(QString::fromWCharArray(L"修改"), [this, node]{
emit acitonTrigger_updateModel(node->data(Qt::UserRole + NodeDataRole::ID).toInt());
});
menu.addAction(QString::fromWCharArray(L"添加属性组"), [this, node]{
emit actionTrigger_addGroup(node->data(Qt::UserRole + NodeDataRole::ID).toInt());
});
@ -343,3 +347,19 @@ void DBStructureView::showContextMenu(const QPoint& pos)
menu.exec(originPoint + pos);
}
}
void DBStructureView::onSIG_updateConnectionName(const QString& oldName, const QString& newName)
{
DBStructureModel* model = dynamic_cast<DBStructureModel*>(this->model());
if(model && m_dbManager)
{
QModelIndex index = model->getConnNodeIndex(oldName);
if(index.isValid())
{
model->setData(index, newName);
if(m_curConnection == oldName)
m_curConnection = newName;
}
}
}

View File

@ -123,7 +123,7 @@ void GroupSelectionDialog::onBtnClicked_save()
}
QString connection = m_pMainWindow->getCurConnection();
bool result = SqlQueryExecutor::instance().addModleGrpus(connection, m_curModelID, groups);
bool result = SqlQueryExecutor::instance().addModleGroups(connection, m_curModelID, groups);
if(!result)
{
m_pMainWindow->showMessageDialog(type_warning, QString::fromWCharArray(L"错误"),QString::fromWCharArray(L"信息存储失败,详情可见日志文件"));

View File

@ -83,6 +83,7 @@ void MainWindow::initialize()
m_pDBStrutureView = new DBStructureView(m_dbManager, this);
m_pDBStrutureView->setMainWindow(this);
connect(m_pDBStrutureView, &DBStructureView::actionTrigger_addModel, this, &MainWindow::onActionTrigger_addModel);
connect(m_pDBStrutureView, &DBStructureView::acitonTrigger_updateModel, this, &MainWindow::onActionTrigger_updateModel);
connect(m_pDBStrutureView, &DBStructureView::actionTrigger_addGroup, this, &MainWindow::onActionTrigger_addGroup);
connect(m_pDBStrutureView, &DBStructureView::openAttributeInfo, this, &MainWindow::onSIG_openAttributeInfo);
connect(m_pDBStrutureView, &DBStructureView::closeAttributeInfo, this, &MainWindow::onSIG_closeAttributeInfo);
@ -225,6 +226,39 @@ void MainWindow::onActionTrigger_addModel()
m_pModelInfoDialog->exec();
}
}
void MainWindow::onActionTrigger_updateModel(int modelID)
{
if(m_pModelInfoDialog && m_pModelInfoDialog->isVisible())
return;
if(m_pModelInfoDialog == nullptr)
{
m_pModelInfoDialog = new ModelInfoEditDialog(this);
m_pModelInfoDialog->setMainWindow(this);
m_pModelInfoDialog->installEventFilter(this);
connect(m_pModelInfoDialog, &ModelInfoEditDialog::addModel, this, &MainWindow::onSIG_addModel);
connect(m_pModelInfoDialog, &ModelInfoEditDialog::finished, this, [=]{ MaskManager::instance()->hideMask(m_pModelInfoDialog);});
}
int nX = (this->width() - m_pModelInfoDialog->width()) * 0.5;
int nY = (this->height() - m_pModelInfoDialog->height()) * 0.5;
m_pModelInfoDialog->setModel(modelID);
if(QSysInfo::kernelType() == "linux")
{
MaskManager::instance()->showMask(m_pModelInfoDialog);
m_pModelInfoDialog->move(nX, nY);
m_pModelInfoDialog->show();
}
else
{
nX += this->geometry().x();
nY += this->geometry().y();
m_pModelInfoDialog->move(nX, nY);
m_pModelInfoDialog->exec();
}
}
void MainWindow::onActionTrigger_removeModel()
{
if(m_pDBStrutureView)

View File

@ -8,6 +8,9 @@
#include <QRegularExpressionValidator>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QFileDialog>
#include <QSvgRenderer>
#include <QPainter>
#define itemRole_groupID 1
#define itemRole_isPublic 2
@ -39,14 +42,68 @@ ModelInfoEditDialog::~ModelInfoEditDialog()
void ModelInfoEditDialog::showEvent(QShowEvent* e)
{
refreshGroupList();
refreshComponentTypeList();
if(m_state == DS_New)
{
resetUI();
setWindowIcon(QIcon(":/img/images/icon_addTable.png"));
setWindowTitle(QString::fromWCharArray(L"新建模型"));
}
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;
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"获取模型信息失败"));
}
}
QDialog::showEvent(e);
}
void ModelInfoEditDialog::initialize()
@ -64,6 +121,7 @@ void ModelInfoEditDialog::initialize()
ui->sourceList->setItemDelegate(delegate);
ui->selectedList->setItemDelegate(delegate);
connect(ui->btnSelectImage, &QPushButton::clicked, this, &ModelInfoEditDialog::onBtnClicked_selectImage);
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);
@ -74,12 +132,16 @@ void ModelInfoEditDialog::initialize()
void ModelInfoEditDialog::resetUI()
{
ui->tabWidget->setCurrentIndex(0);
ui->tabWidget->setCurrentIndex(0);
ui->lineEdit_modelName->setText("");
ui->lineEdit_modelType->setText("");
ui->lineEdit_modelImage->setText("");
ui->plainTextEdit_modelComment->setPlainText("");
ui->label_error->setText("");
ui->label_error->clear();
ui->modelImagePreview->setPixmap(QPixmap(":/img/images/icon_file.png"));
m_oldName = "";
m_oldType = "";
}
void ModelInfoEditDialog::refreshGroupList()
@ -109,6 +171,20 @@ void ModelInfoEditDialog::refreshGroupList()
}
}
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);
}
}
void ModelInfoEditDialog::setErrorInfo(const QString& info)
{
if(m_pMainWindow)
@ -122,9 +198,17 @@ void ModelInfoEditDialog::setMainWindow(MainWindow* window)
m_pMainWindow = window;
}
void ModelInfoEditDialog::setState(DialogState state)
{
m_state = state;
if(state == DS_New)
m_curModelID = -1;
}
void ModelInfoEditDialog::setModel(int id)
{
m_curModelID = id;
m_state = DS_Edit;
}
void ModelInfoEditDialog::showMask()
@ -137,6 +221,27 @@ 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);
}
void ModelInfoEditDialog::onItemDblCliked_sourceList(QListWidgetItem* item)
{
if(item->data(Qt::UserRole + itemRole_isPublic).toBool())
@ -150,9 +255,32 @@ void ModelInfoEditDialog::onItemDblCliked_sourceList(QListWidgetItem* item)
}
}
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文件加载失败"));
}
void ModelInfoEditDialog::onBtnClicked_save()
{
if(ui->lineEdit_modelName->text() == "" || ui->lineEdit_modelType->text() == "")
if(ui->lineEdit_modelName->text() == "" || ui->lineEdit_modelType->text() == "" || ui->lineEdit_modelImage->text() == ""
|| (ui->grahpicElement->count() > 1 && ui->grahpicElement->currentIndex() == 0))
{
setErrorInfo(QString::fromWCharArray(L"除‘备注’外不能有信息为空"));
return;
@ -177,7 +305,7 @@ void ModelInfoEditDialog::onBtnClicked_save()
//先判断是否存在同名
QString connection = m_pMainWindow->getCurConnection();
bool nameExists = SqlQueryExecutor::instance().modelNameExistsInDB(connection, modelName);
bool nameExists = SqlQueryExecutor::instance().modelNameExistsInDB(connection, modelName, m_oldName);
if(nameExists)
{
setErrorInfo(QString::fromWCharArray(L"已存同名的模型,请修改模型名称"));
@ -186,7 +314,7 @@ void ModelInfoEditDialog::onBtnClicked_save()
}
else //然后判断类型是否存在相同
{
bool typeExists = SqlQueryExecutor::instance().modelTypeExistsInDB(connection, modeType);
bool typeExists = SqlQueryExecutor::instance().modelTypeExistsInDB(connection, modeType, m_oldType);
if(typeExists)
{
setErrorInfo(QString::fromWCharArray(L"已存同类型的模型,请修改模型类型"));
@ -195,13 +323,42 @@ void ModelInfoEditDialog::onBtnClicked_save()
}
}
//向数据库中插入数据(因为提供了连续添加的功能,所以向数据库中插入数据放在这里执行)
Model modle(-1, modelName, modeType, remark, groups);
bool result = SqlQueryExecutor::instance().addModel(connection, modle);
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);
}
if(result)
{
emit addModel(modle);
if(m_state == DS_New)
{
emit addModel(model);
m_pMainWindow->showMessageDialog(type_question, QString::fromWCharArray(L"成功"),QString::fromWCharArray(L"信息存储完成,是否继续添加模型"));
if(g_msgDlgBtn == btn_No)
close();
@ -211,6 +368,22 @@ void ModelInfoEditDialog::onBtnClicked_save()
refreshGroupList();
}
}
else if(m_state == DS_Edit)
{
if(modelName != m_oldName) //更新对应树节点
{
}
//计算删除和添加的属性组-转化为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();
}
}
else
setErrorInfo(QString::fromWCharArray(L"信息存储失败,详情可见日志文件"));
}

View File

@ -193,7 +193,7 @@ QHash<QString, QString> SqlQueryExecutor::getFiledType(const QString& connection
const QVector<Model> SqlQueryExecutor::getModels(const QString& connectionName)
{
QVector<Model> models;
QString strSQL = "SELECT id, model_type, model_name, remark FROM basic.model_type ORDER BY id ASC";
QString strSQL = "SELECT id, model_type, model_name, remark, icon, graphic_element FROM basic.model_type ORDER BY id ASC";
try
{
QSqlQuery query = executeSQL(connectionName, strSQL);
@ -203,8 +203,10 @@ const QVector<Model> SqlQueryExecutor::getModels(const QString& connectionName)
QString type = query.value(1).toString();
QString name = query.value(2).toString();
QString remark = query.value(3).toString();
QByteArray icon = query.value(4).toByteArray();
int grahpicElement = query.value(5).toInt();
QVector<int> groups = getModelGroups(connectionName, id);
models.emplace_back(id, name, type, remark, groups);
models.emplace_back(id, name, type, remark, icon, grahpicElement, groups);
}
}
catch (const DatabaseException& e)
@ -268,12 +270,14 @@ bool SqlQueryExecutor::addModel(const QString& connectionName, Model& model)
int modelID = -1;
//先向model_type中插入一条记录
QString strSQL = "INSERT INTO basic.model_type (model_type, model_name, remark) VALUES "
"(:type, :name, :remark)";
QString strSQL = "INSERT INTO basic.model_type (model_type, model_name, remark, icon, graphic_element) VALUES "
"(:type, :name, :remark, :icon, :graphicElement)";
QVariantHash params;
params.insert(":type", model.type);
params.insert(":name", model.name);
params.insert(":remark", model.remark);
params.insert(":icon", model.icon);
params.insert(":graphicElement", model.grahicElement);
try
{
QSqlQuery query = executeSQL(connectionName, strSQL, params);
@ -354,9 +358,62 @@ bool SqlQueryExecutor::addModel(const QString& connectionName, Model& model)
return true;
}
bool SqlQueryExecutor::modelNameExistsInDB(const QString& connectionName, const QString& name)
bool SqlQueryExecutor::updateModelInfo(const QString& connectionName, Model& model)
{
QString strSQL = "UPDATE basic.model_type SET model_type = :type, model_name = :name, remark = :remark, icon = :icon, graphic_element = :graphicElement WHERE id = :id";
QVariantHash params;
params.insert(":type", model.type);
params.insert(":name", model.name);
params.insert(":remark", model.remark);
params.insert(":icon", model.icon);
params.insert(":graphicElement", model.grahicElement);
params.insert(":id", model.id);
try
{
executeSQL(connectionName, strSQL, params, true);
}
catch (const DatabaseException& e)
{
return false;
}
return true;
}
Model SqlQueryExecutor::getModelInfo(const QString& connectionName, int modelID)
{
QString strSQL = "SELECT model_type, model_name, remark, icon, graphic_element FROM basic.model_type WHERE id = :id";
QVariantHash params;
params.insert(":id", modelID);
try
{
QSqlQuery query = executeSQL(connectionName, strSQL, params);
while(query.next())
{
QString type = query.value(0).toString();
QString name = query.value(1).toString();
QString remark = query.value(2).toString();
QByteArray icon = query.value(3).toByteArray();
int grahpicElement = query.value(4).toInt();
QVector<int> groups = getModelGroups(connectionName, modelID);
return Model(modelID, name, type, remark, icon, grahpicElement, groups);
}
}
catch (const DatabaseException& e)
{
LOG_ERROR("SQL", QString::fromWCharArray(L"获取模型信息失败id:%1").arg(modelID));
}
QVector<int> groups;
return Model(modelID, "", "", "", QByteArray(), 0, groups);
}
bool SqlQueryExecutor::modelNameExistsInDB(const QString& connectionName, const QString& name, const QString& skipCheckName)
{
bool exists = false;
if(name == skipCheckName)
return exists;
QString strSQL = "SELECT id FROM basic.model_type WHERE model_name = \'" + name + "\'";
try
{
@ -371,9 +428,12 @@ bool SqlQueryExecutor::modelNameExistsInDB(const QString& connectionName, const
return exists;
}
bool SqlQueryExecutor::modelTypeExistsInDB(const QString& connectionName, const QString& type)
bool SqlQueryExecutor::modelTypeExistsInDB(const QString& connectionName, const QString& type, const QString& skipCheckType)
{
bool exists = false;
if(type == skipCheckType)
return exists;
QString strSQL = "SELECT id FROM basic.model_type WHERE model_type = \'" + type + "\'";
try
{
@ -405,7 +465,7 @@ bool SqlQueryExecutor::removeModel(const QString& connectionName, int modelID)
return true;
}
bool SqlQueryExecutor::addModleGrpus(const QString& connectionName, int modelID, QVector<int> groups)
bool SqlQueryExecutor::addModleGroups(const QString& connectionName, int modelID, QVector<int> groups)
{
//属于批量操作,需要开启事务
QSqlDatabase db = QSqlDatabase::database(connectionName);
@ -939,3 +999,46 @@ bool SqlQueryExecutor::batchUpdateAttributes(const QString& connectionName, int
return true;
}
const QVector<Component> SqlQueryExecutor::getComponents(const QString& connectionName)
{
QVector<Component> components;
QString strSQL = "SELECT id, type, name FROM public.component_type ORDER BY id ASC";
try
{
QSqlQuery query = executeSQL(connectionName, strSQL);
while(query.next())
{
int id = query.value(0).toInt();
QString type = query.value(1).toString();
QString name = query.value(2).toString();
components.emplace_back(id, type, name); //直接调用构造函数,避免拷贝
}
}
catch (const DatabaseException& e)
{
LOG_ERROR("SQL", QString::fromWCharArray(L"获取Components失败"));
}
return components;
}
const QString SqlQueryExecutor::getComponentName(const QString& connectionName, int id)
{
QString name = "";
QString strSQL = "SELECT name FROM public.component_type WHERE id = :id";
QVariantHash params;
params.insert(":id", id);
try
{
QSqlQuery query = executeSQL(connectionName, strSQL, params);
if(query.next())
name = query.value(0).toString();
}
catch (const DatabaseException& e)
{
LOG_ERROR("SQL", QString::fromWCharArray(L"获取component名称失败id:%1").arg(QString::number(id)));
}
return name;
}

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>372</width>
<height>335</height>
<height>346</height>
</rect>
</property>
<property name="windowTitle">
@ -58,8 +58,8 @@
<property name="verticalSpacing">
<number>15</number>
</property>
<item row="1" column="0">
<widget class="QLabel" name="label_modelType">
<item row="4" column="0">
<widget class="QLabel" name="label_modelComment">
<property name="minimumSize">
<size>
<width>71</width>
@ -73,7 +73,26 @@
</size>
</property>
<property name="text">
<string>模型类别:</string>
<string>备 注:</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_modelImage_2">
<property name="minimumSize">
<size>
<width>71</width>
<height>21</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>71</width>
<height>21</height>
</size>
</property>
<property name="text">
<string>图元类型:</string>
</property>
</widget>
</item>
@ -115,8 +134,121 @@
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_modelComment">
<item row="4" column="1">
<widget class="QPlainTextEdit" name="plainTextEdit_modelComment">
<property name="styleSheet">
<string notr="true"/>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QWidget" name="widgetImage" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLineEdit" name="lineEdit_modelImage">
<property name="minimumSize">
<size>
<width>0</width>
<height>21</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>21</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="modelImagePreview">
<property name="minimumSize">
<size>
<width>21</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>21</width>
<height>16777215</height>
</size>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnSelectImage">
<property name="minimumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QPushButton
{
border: 0px;
border-radius:0px;
}
QPushButton:hover
{
background-color:rgba(70,130,180,35);
}
QPushButton:pressed
{
background-color:rgba(70,130,180,65);
}</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resource/PowerModeler.qrc">
<normaloff>:/img/images/icon_ellipsis.png</normaloff>:/img/images/icon_ellipsis.png</iconset>
</property>
<property name="default">
<bool>false</bool>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_modelType">
<property name="minimumSize">
<size>
<width>71</width>
@ -130,19 +262,12 @@
</size>
</property>
<property name="text">
<string>备 注:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QPlainTextEdit" name="plainTextEdit_modelComment">
<property name="styleSheet">
<string notr="true"/>
<string>模型类别:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QWidget" name="widget" native="true">
<widget class="QWidget" name="widgetType" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>0</number>
@ -187,7 +312,7 @@
<string notr="true">color: rgb(255, 0, 0);</string>
</property>
<property name="text">
<string>类别必须为英文</string>
<string>*类别必须为英文</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
@ -198,7 +323,7 @@
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_modelType_2">
<widget class="QLabel" name="label_modelImage">
<property name="minimumSize">
<size>
<width>71</width>
@ -216,6 +341,61 @@
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QWidget" name="widgetGraphicElement" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<property name="spacing">
<number>3</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QComboBox" name="grahpicElement">
<property name="minimumSize">
<size>
<width>0</width>
<height>26</height>
</size>
</property>
<item>
<property name="text">
<string>未选择</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="label_tip_2">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">color: rgb(255, 0, 0);</string>
</property>
<property name="text">
<string>*必选,创建工程模时使用</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_group">