From 668aef03c1c0981706a7b153af6185df5bb4a688 Mon Sep 17 00:00:00 2001 From: duanshengchao <519970194@qq.com> Date: Fri, 30 May 2025 18:51:23 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E2=80=98=E8=BF=9E=E6=8E=A5?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E2=80=99=E5=8A=A8=E6=80=81=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 4 +- CMakeLists.txt.autosave | 164 ----------------------- include/dbManager.h | 1 + include/dbStructureModel.h | 1 + include/dbStructureNode.h | 1 + include/dbStructureView.h | 2 + include/global.h | 18 ++- include/mainwindow.h | 1 + include/modelInfoEditDialog.h | 11 +- include/sqlQueryExecutor.h | 11 +- resource/PowerModeler.qrc | 2 + resource/images/icon_ellipsis.png | Bin 0 -> 293 bytes resource/images/icon_file.png | Bin 0 -> 284 bytes source/connectionDialog.cpp | 12 +- source/dbManager.cpp | 23 +++- source/dbStructureModel.cpp | 12 ++ source/dbStructureNode.cpp | 7 +- source/dbStructureView.cpp | 20 +++ source/groupSelectionDialog.cpp | 2 +- source/mainwindow.cpp | 34 +++++ source/modelInfoEditDialog.cpp | 203 +++++++++++++++++++++++++--- source/sqlQueryExecutor.cpp | 117 +++++++++++++++- ui/modelInfoEditDialog.ui | 214 +++++++++++++++++++++++++++--- 23 files changed, 645 insertions(+), 215 deletions(-) delete mode 100644 CMakeLists.txt.autosave create mode 100644 resource/images/icon_ellipsis.png create mode 100644 resource/images/icon_file.png diff --git a/CMakeLists.txt b/CMakeLists.txt index 0808303..05fbc35 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/CMakeLists.txt.autosave b/CMakeLists.txt.autosave deleted file mode 100644 index a340108..0000000 --- a/CMakeLists.txt.autosave +++ /dev/null @@ -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() diff --git a/include/dbManager.h b/include/dbManager.h index e320af7..1c348da 100644 --- a/include/dbManager.h +++ b/include/dbManager.h @@ -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 m_configs; diff --git a/include/dbStructureModel.h b/include/dbStructureModel.h index 2ae99f0..cbd6d71 100644 --- a/include/dbStructureModel.h +++ b/include/dbStructureModel.h @@ -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; //业务功能接口 diff --git a/include/dbStructureNode.h b/include/dbStructureNode.h index 247911b..87c4235 100644 --- a/include/dbStructureNode.h +++ b/include/dbStructureNode.h @@ -51,6 +51,7 @@ public: //数据访问 NodeType type() const; QString name() const; + void setName(const QString&); QIcon icon() const; void setStatus(NodeStatus); NodeStatus status() const; diff --git a/include/dbStructureView.h b/include/dbStructureView.h index 0cbc42a..35382aa 100644 --- a/include/dbStructureView.h +++ b/include/dbStructureView.h @@ -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 diff --git a/include/global.h b/include/global.h index e4e5d35..a383f2a 100644 --- a/include/global.h +++ b/include/global.h @@ -74,13 +74,17 @@ struct Model QString name; //中文展示名称 QString type; //英文标识名称 QString remark; + QByteArray icon; + int grahicElement; QVector groups; - Model(int id, QString name, QString type, QString remark, QVector groups) + Model(int id, QString name, QString type, QString remark, QByteArray icon, int grahicElement, QVector 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: diff --git a/include/mainwindow.h b/include/mainwindow.h index 07838ce..92b03fc 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -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); diff --git a/include/modelInfoEditDialog.h b/include/modelInfoEditDialog.h index b11f2a8..282e05c 100644 --- a/include/modelInfoEditDialog.h +++ b/include/modelInfoEditDialog.h @@ -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 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(); diff --git a/include/sqlQueryExecutor.h b/include/sqlQueryExecutor.h index 988d517..8816ec8 100644 --- a/include/sqlQueryExecutor.h +++ b/include/sqlQueryExecutor.h @@ -33,10 +33,12 @@ public: const QVector 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); + bool addModleGroups(const QString&, int, QVector); QVector 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); bool batchDeleteAttributes(const QString&, int, int, QList); bool batchUpdateAttributes(const QString&, int, int, QList); + //其它 + const QVector getComponents(const QString&); + const QString getComponentName(const QString&, int); signals: void errorOccurred(const QString& error); diff --git a/resource/PowerModeler.qrc b/resource/PowerModeler.qrc index 6ea746d..35558b4 100644 --- a/resource/PowerModeler.qrc +++ b/resource/PowerModeler.qrc @@ -1,5 +1,7 @@ + images/icon_ellipsis.png + images/icon_file.png images/icon_multiple-choice.png images/icon_multiple-choice_disable.png images/icon_hierarchy_unchecked.png diff --git a/resource/images/icon_ellipsis.png b/resource/images/icon_ellipsis.png new file mode 100644 index 0000000000000000000000000000000000000000..118d06cb17cda5c2bd9a232434ec21f80fdb77a2 GIT binary patch literal 293 zcmeAS@N?(olHy`uVBq!ia0vp^av;pX1|+Qw)-3{3oCO|{#S9GG!XV7ZFl&wkQ1H5^ zi(^Q|oVSy_`4}BVT>X{SFbcn6=>8ztB@xkmUS{_PNsr?z+;bWYzct8m1f7%)(OU1K z(sR%A-ICv5cE?t-wk1jc(Xst28MGg;ylI&B=t+ZN!GxYCksi@$J0iUo$Y|>_nLl{> zl(B?4U)Vy=^TC%V(f4;Uv97IH##3Th9P=ByF;Oxqx=r%9v8_Sd~?=qddxjRy=iwP_s_?=7XoC;o7)e>88K|? mx;{lR@0yIpQ7_)Qlibs6G7oD!+N}iiB7>)^pUXO@geCyjW^g#J5eO+5PV{D1WcSsTl~rfzszmL0e9(%Gcny!!uNhr}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; diff --git a/source/dbManager.cpp b/source/dbManager.cpp index 9b5f19e..4b22fd8 100644 --- a/source/dbManager.cpp +++ b/source/dbManager.cpp @@ -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) diff --git a/source/dbStructureModel.cpp b/source/dbStructureModel.cpp index c4348d9..78f2eb0 100644 --- a/source/dbStructureModel.cpp +++ b/source/dbStructureModel.cpp @@ -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(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) diff --git a/source/dbStructureNode.cpp b/source/dbStructureNode.cpp index c6a6f14..69f60f0 100644 --- a/source/dbStructureNode.cpp +++ b/source/dbStructureNode.cpp @@ -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; @@ -126,7 +131,7 @@ NodeStatus DBStructureNode::status() const QVariant DBStructureNode::columnData(int column) const { - switch(column) + switch(column) { case ColumnName: return m_name; diff --git a/source/dbStructureView.cpp b/source/dbStructureView.cpp index f9cddc3..ba1ab3f 100644 --- a/source/dbStructureView.cpp +++ b/source/dbStructureView.cpp @@ -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(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; + } + + } +} diff --git a/source/groupSelectionDialog.cpp b/source/groupSelectionDialog.cpp index bea7458..30acca1 100644 --- a/source/groupSelectionDialog.cpp +++ b/source/groupSelectionDialog.cpp @@ -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"信息存储失败,详情可见日志文件")); diff --git a/source/mainwindow.cpp b/source/mainwindow.cpp index a0b88b3..1feafb0 100644 --- a/source/mainwindow.cpp +++ b/source/mainwindow.cpp @@ -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) diff --git a/source/modelInfoEditDialog.cpp b/source/modelInfoEditDialog.cpp index 2c5513e..94e82da 100644 --- a/source/modelInfoEditDialog.cpp +++ b/source/modelInfoEditDialog.cpp @@ -8,6 +8,9 @@ #include #include #include +#include +#include +#include #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 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,20 +323,65 @@ 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); - m_pMainWindow->showMessageDialog(type_question, QString::fromWCharArray(L"成功"),QString::fromWCharArray(L"信息存储完成,是否继续添加模型")); - if(g_msgDlgBtn == btn_No) - close(); - else + if(m_state == DS_New) { - resetUI(); - refreshGroupList(); + 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) //更新对应树节点 + { + + } + //计算删除和添加的属性组-转化为QSet,然后利用QSet的‘-’运算符操作 + QSet oldSet(m_oldGroups.begin(), m_oldGroups.end()); + QSet newSet(model.groups.begin(), model.groups.end()); + QSet added = newSet - oldSet; + QSet removed = oldSet - newSet; + + + close(); } } else diff --git a/source/sqlQueryExecutor.cpp b/source/sqlQueryExecutor.cpp index dff4a93..2fea43c 100644 --- a/source/sqlQueryExecutor.cpp +++ b/source/sqlQueryExecutor.cpp @@ -193,7 +193,7 @@ QHash SqlQueryExecutor::getFiledType(const QString& connection const QVector SqlQueryExecutor::getModels(const QString& connectionName) { QVector 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 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 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 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 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 groups) +bool SqlQueryExecutor::addModleGroups(const QString& connectionName, int modelID, QVector groups) { //属于批量操作,需要开启事务 QSqlDatabase db = QSqlDatabase::database(connectionName); @@ -939,3 +999,46 @@ bool SqlQueryExecutor::batchUpdateAttributes(const QString& connectionName, int return true; } + +const QVector SqlQueryExecutor::getComponents(const QString& connectionName) +{ + QVector 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; +} diff --git a/ui/modelInfoEditDialog.ui b/ui/modelInfoEditDialog.ui index 7d0fd11..f59520c 100644 --- a/ui/modelInfoEditDialog.ui +++ b/ui/modelInfoEditDialog.ui @@ -7,7 +7,7 @@ 0 0 372 - 335 + 346 @@ -58,8 +58,8 @@ 15 - - + + 71 @@ -73,7 +73,26 @@ - 模型类别: + 备 注: + + + + + + + + 71 + 21 + + + + + 71 + 21 + + + + 图元类型: @@ -115,8 +134,121 @@ - - + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 21 + + + + + 16777215 + 21 + + + + + + + true + + + + + + + + 21 + 0 + + + + + 21 + 16777215 + + + + + + + + + + + + + + + 21 + 21 + + + + + 21 + 21 + + + + QPushButton +{ + border: 0px; + border-radius:0px; +} +QPushButton:hover +{ + background-color:rgba(70,130,180,35); +} +QPushButton:pressed +{ + background-color:rgba(70,130,180,65); +} + + + + + + + :/img/images/icon_ellipsis.png:/img/images/icon_ellipsis.png + + + false + + + false + + + + + + + + 71 @@ -130,19 +262,12 @@ - 备 注: - - - - - - - + 模型类别: - + 0 @@ -187,7 +312,7 @@ color: rgb(255, 0, 0); - 类别必须为英文 + *类别必须为英文 Qt::AlignmentFlag::AlignCenter @@ -198,7 +323,7 @@ - + 71 @@ -216,6 +341,61 @@ + + + + + 3 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 26 + + + + + 未选择 + + + + + + + + + 100 + 0 + + + + color: rgb(255, 0, 0); + + + *必选,创建工程模时使用 + + + Qt::AlignmentFlag::AlignCenter + + + + + +