From f9ff317b4688a2ea128376a9a1f2ad85ef74f2d1 Mon Sep 17 00:00:00 2001 From: duanshengchao <519970194@qq.com> Date: Mon, 24 Mar 2025 18:13:06 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=8F=8C=E5=87=BB=E2=80=98?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E7=BB=84=E2=80=99=E8=8A=82=E7=82=B9=E6=89=93?= =?UTF-8?q?=E5=BC=80=E5=B1=9E=E6=80=A7=E6=95=B0=E6=8D=AE=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=E9=9D=A2=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 10 +- CMakeLists.txt.user | 2 +- include/attributeTableModel.h | 80 ++++++++++++ include/attributeView.h | 33 +++++ include/customTab.h | 41 ++++++ include/dbBrowser.h | 14 ++- include/dbStructureView.h | 2 + include/global.h | 13 ++ include/logger.h | 1 - include/mainwindow.h | 1 + include/sqlQueryExecutor.h | 3 +- include/tableEditModel.h | 61 +++++++++ resource/PowerModeler.qrc | 3 + resource/images/btn_close_default.png | Bin 0 -> 178 bytes resource/images/btn_close_hover.png | Bin 0 -> 200 bytes resource/images/btn_close_pressed.png | Bin 0 -> 197 bytes source/attributeTableModel.cpp | 172 ++++++++++++++++++++++++++ source/attributeView.cpp | 25 ++++ source/customTab.cpp | 62 ++++++++++ source/dbBrowser.cpp | 31 +++++ source/dbStructureModel.cpp | 2 +- source/dbStructureView.cpp | 15 ++- source/logger.cpp | 1 + source/mainwindow.cpp | 7 ++ source/sqlQueryExecutor.cpp | 20 ++- source/tableEditModel.cpp | 101 +++++++++++++++ source/tableWidgetHoverDelegate.cpp | 2 +- ui/dbBrowser.ui | 38 +----- 28 files changed, 697 insertions(+), 43 deletions(-) create mode 100644 include/attributeTableModel.h create mode 100644 include/attributeView.h create mode 100644 include/customTab.h create mode 100644 include/tableEditModel.h create mode 100644 resource/images/btn_close_default.png create mode 100644 resource/images/btn_close_hover.png create mode 100644 resource/images/btn_close_pressed.png create mode 100644 source/attributeTableModel.cpp create mode 100644 source/attributeView.cpp create mode 100644 source/customTab.cpp create mode 100644 source/tableEditModel.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 776f594..46642cc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ set(CMAKE_AUTOUIC_SEARCH_PATHS "ui") set(H_HEADER_FILES include/global.h include/logger.h - include/mainWindow.h + include/mainwindow.h include/dbManager.h include/dbBrowser.h include/dbStructureNode.h @@ -32,13 +32,15 @@ set(H_HEADER_FILES include/customMenu.h include/modelInfoEditDialog.h include/sqlQueryExecutor.h + include/attributeTableModel.h + include/attributeView.h ) set(CPP_SOURCE_FILES source/main.cpp source/global.cpp source/logger.cpp - source/mainWindow.cpp + source/mainwindow.cpp source/dbManager.cpp source/dbBrowser.cpp source/dbStructureNode.cpp @@ -51,10 +53,12 @@ set(CPP_SOURCE_FILES source/customMenu.cpp source/modelInfoEditDialog.cpp source/sqlQueryExecutor.cpp + source/attributeTableModel.cpp + source/attributeView.cpp ) set(UI_FILES - ui/mainWindow.ui + ui/mainwindow.ui ui/dbBrowser.ui ui/connectionDialog.ui ui/messageDialog.ui diff --git a/CMakeLists.txt.user b/CMakeLists.txt.user index 702be04..a1fa6e3 100644 --- a/CMakeLists.txt.user +++ b/CMakeLists.txt.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/include/attributeTableModel.h b/include/attributeTableModel.h new file mode 100644 index 0000000..c713d1c --- /dev/null +++ b/include/attributeTableModel.h @@ -0,0 +1,80 @@ +#ifndef ATTRIBUTETABLEMODEL_H +#define ATTRIBUTETABLEMODEL_H + +/** + * @brief 用来处理attribute数据的Model类 + * + * 基本功能包括: + * 1、可以自定义显示数据表中的哪些列 + * 2、可以分页显示并自定义每页展示数量 + * 3、编辑的数据可以突出展示(如加粗、改色) + * 4、最前方加入一个用于展示行号的列(行号从1开始) + * 5、点击行号列可以实现选中标识(通过icon) + * 6、哪一行被编辑,改行的行号指示可以加*进行标识 + * + */ + +#include +#include + +class AttributeTableModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + enum EditState + { + Clean = 0, + Modified, + New, + Deleted + }; + + explicit AttributeTableModel(QObject* parent = nullptr + , const QString& connection = "" + , const QString& modelID = "" + , const QString& groupID = "" + , const QString& tableName = "basic.attribute"); + ~AttributeTableModel(); + + QVariant data(const QModelIndex& index, int role) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + int rowCount(const QModelIndex& parent = QModelIndex()) const override; + int columnCount(const QModelIndex& parent = QModelIndex()) const override; + Qt::ItemFlags flags(const QModelIndex &index) const override; + + //分页控制 + void setPageSize(int); + int pageSize() const; + void setCurrentPage(int); + int currentPage() const; + int totalPages() const; + + //展示列控制 + void setVisibleColumns(const QStringList& columns); + +private: + struct RowData + { + QSqlRecord record; + EditState state = Clean; + }; + + void loadPageData(); // 加载当前页数据 + void updateTotalCount(); // 更新总记录数 + + QString m_connection; + QString m_modelID; + QString m_groupID; + QString m_tableName; + + int m_pageSize; + int m_currentPage; + int m_totalCount; + QStringList m_visibleColumns; + QList m_currentPageData; + QHash m_modifiedRows; //key:global row number +}; + +#endif //ATTRIBUTETABLEMODEL_H diff --git a/include/attributeView.h b/include/attributeView.h new file mode 100644 index 0000000..13c6e06 --- /dev/null +++ b/include/attributeView.h @@ -0,0 +1,33 @@ +#ifndef ATTRIBUTEVIEW_H +#define ATTRIBUTEVIEW_H + +#include + +class QTableView; +class AttributeTableModel; +class QVBoxLayout; + +class AttributeView : public QWidget +{ + Q_OBJECT + +public: + AttributeView(QWidget *parent = nullptr + , const QString& connection = "" + , const QString& modelID = "" + , const QString& groupID = "" + , const QString& tableName = "basic.attribute"); + ~AttributeView(); + +private: + QString m_connection; + QString m_modelID; + QString m_groupID; + QString m_attributeTable; + + QTableView* m_tableView; + AttributeTableModel* m_attributeTableModel; + QVBoxLayout* m_vLayout; +}; + +#endif //ATTRIBUTEVIEW_H diff --git a/include/customTab.h b/include/customTab.h new file mode 100644 index 0000000..3d5d042 --- /dev/null +++ b/include/customTab.h @@ -0,0 +1,41 @@ +#ifndef CUSTOMTAB_H +#define CUSTOMTAB_H + +#include + +class QLabel; +class QPushButton; +class QBoxLayout; +class CustomTab : public QWidget +{ + Q_OBJECT + +public: + CustomTab(QWidget *parent = nullptr); + virtual ~CustomTab(); + + void setText(const QString&); + const QString text(); + + void setIcon(const QIcon&); + +signals: + void closeTab(QWidget*); + +protected: + void enterEvent(QEnterEvent*); + void leaveEvent(QEvent*); + +private slots: + void onCloseButtonClicked(); + +private: + QIcon m_Icon; + QSize m_IconSize; + QLabel* m_pIconLabel; + QLabel* m_pTitle; + QPushButton* m_pCloseBtn; + QBoxLayout* m_pLayout; +}; + +#endif //CUSTOMTAB_H diff --git a/include/dbBrowser.h b/include/dbBrowser.h index 6e55f0f..cf8b952 100644 --- a/include/dbBrowser.h +++ b/include/dbBrowser.h @@ -1,3 +1,7 @@ +#ifndef DBBROWSER_H +#define DBBROWSER_H + +#include "global.h" #include QT_BEGIN_NAMESPACE @@ -6,7 +10,7 @@ class DatabaseBrowser; } QT_END_NAMESPACE - +class AttributeView; class DatabaseBrowser : public QWidget { Q_OBJECT @@ -15,6 +19,14 @@ public: DatabaseBrowser(QWidget *parent = nullptr); ~DatabaseBrowser(); + void addTab_attribute(const QString&, ModelAttributeGroup&); + +private slots: + void closeTab(QWidget*); + private: Ui::DatabaseBrowser *ui; + QList m_attributeViewList; }; + +#endif //DBBROWSER_H diff --git a/include/dbStructureView.h b/include/dbStructureView.h index f0c731e..c62a5c8 100644 --- a/include/dbStructureView.h +++ b/include/dbStructureView.h @@ -1,6 +1,7 @@ #ifndef DBSTRUCTUREVIEW_H #define DBSTRUCTUREVIEW_H +#include "global.h" #include class MainWindow; @@ -36,6 +37,7 @@ private: signals: void actionTrigger_addModel(); + void openAttributeInfo(const QString&, ModelAttributeGroup&); private slots: void itemDoubleClick(const QModelIndex&); diff --git a/include/global.h b/include/global.h index 5950e7b..134ac67 100644 --- a/include/global.h +++ b/include/global.h @@ -72,6 +72,19 @@ struct Model }; +struct ModelAttributeGroup +{ + int modelID; + int groupID; + QString strModelName; + QString strGroupName; + + ModelAttributeGroup(int modelID, int groupID, QString strModelName, QString strGroupName) + : modelID(modelID), + groupID(groupID), + strModelName(std::move(strModelName)), + strGroupName(std::move(strGroupName)){} +}; class DatabaseException : public std::runtime_error { diff --git a/include/logger.h b/include/logger.h index 0e5fa6c..a9dd5f6 100644 --- a/include/logger.h +++ b/include/logger.h @@ -3,7 +3,6 @@ #include #include -#include #include // 日志宏定义 diff --git a/include/mainwindow.h b/include/mainwindow.h index 42f04b7..5376e84 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -58,6 +58,7 @@ private slots: void onSIG_errorFormSQLExecutor(const QString& error); void onSIG_connectionStatusChanged(const QString& strConnectionName, bool bConnected); void onSIG_addModel(Model&); + void onSIG_openAttributeInfo(const QString&, ModelAttributeGroup&); }; #endif // MAINWINDOW_H diff --git a/include/sqlQueryExecutor.h b/include/sqlQueryExecutor.h index 71f8871..20d2030 100644 --- a/include/sqlQueryExecutor.h +++ b/include/sqlQueryExecutor.h @@ -28,7 +28,8 @@ public: bool addModel(const QString&, Model&); bool modelNameExistsInDB(const QString&, const QString&); bool modelTypeExistsInDB(const QString&, const QString&); - bool removeMode(const QString&, int); + bool removeModel(const QString&, int); + int getAttributeCount(const QString&, const QString&); signals: void errorOccurred(const QString& error); diff --git a/include/tableEditModel.h b/include/tableEditModel.h new file mode 100644 index 0000000..14cd2a5 --- /dev/null +++ b/include/tableEditModel.h @@ -0,0 +1,61 @@ +#ifndef TABLEEDITMODEL_H +#define TABLEEDITMODEL_H + +/** + * @brief 用来加载显示数据库中数据表的Model类 + * + * 基本功能包括: + * 1、可以自定义显示数据表中的哪些列 + * 2、可以分页显示并自定义每页展示数量 + * 3、编辑的数据可以突出展示(如加粗、改色) + * 4、最前方加入一个用于展示行号的列(行号从1开始) + * 5、点击行号列可以实现选中标识(通过icon) + * 6、哪一行被编辑,改行的行号指示可以加*进行标识 + * + */ + +#include +#include + +class TableEditModel : public QSqlTableModel +{ + Q_OBJECT +public: + explicit TableEditModel(QObject* parent = nullptr, const QSqlDatabase& db = QSqlDatabase(), const QStringList &visibleColumns = {}); + ~TableEditModel(); + + QVariant data(const QModelIndex& index, int role) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + int columnCount(const QModelIndex& parent = QModelIndex()) const override; + Qt::ItemFlags flags(const QModelIndex &index) const override; + + //分页控制 + void setPageSize(int); + int pageSize() const; + void setCurrentPage(int); + int currentPage() const; + int totalPages() const; + + //展示列控制 + void setVisibleColumns(const QStringList& columns); + +protected: + QString selectStatement() const override; //调用select()时会使用该函数重写后返回的语句 + +private: + struct EditRecord //编辑记录 + { + QSqlRecord original; + QSqlRecord modified; + bool isNew = false; + bool isDeleted = false; + }; + + int m_pageSize; + int m_currentPage; + int m_totalRecords; + QStringList m_visibleColumns; + QHash m_editCache; //key:当前页中的row +}; + +#endif //TABLEEDITMODEL_H diff --git a/resource/PowerModeler.qrc b/resource/PowerModeler.qrc index d3810a3..1d1c224 100644 --- a/resource/PowerModeler.qrc +++ b/resource/PowerModeler.qrc @@ -1,5 +1,8 @@ + images/btn_close_pressed.png + images/btn_close_default.png + images/btn_close_hover.png images/icon_first.png images/icon_last.png images/icon_next.png diff --git a/resource/images/btn_close_default.png b/resource/images/btn_close_default.png new file mode 100644 index 0000000000000000000000000000000000000000..76de3059e7e70586bde9623b28496c51ccaae2fd GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9GG!XV7ZFl&wkP%y>Q z#WAE}&e=(hTn7v|Se_?3Ejj;&d-k419F|)Rqnt9oKRS4`RrI0%t;R_Ywrn;RUBISz zOLDd|X92_P&8yGpv0Q#O@!`gwx5{t*+{zHSQbF5&3a3O{#-jCaXC1#$o!0ks-zRe` Z#uIzxn)p|_Zw1=N;OXk;vd$@?2>{KJK~w+$ literal 0 HcmV?d00001 diff --git a/resource/images/btn_close_hover.png b/resource/images/btn_close_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..469bd78995b072620558ae5388178ff356aed8d2 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9GG!XV7ZFl&wkP_W9= z#WAE}&fZDhTn7v|Tx@47crwE>agw*s#InFohD)dEsc_c{yR|#Ccw8)JvSe1O_V_wS zmc^wZs#dT$_t?FatZ55G6qX8Zn|Cm_UyfJr!B?T5Y!(~pS@-@an^!ONpo6tfXX4!Z u+tRNXs$AZ?WgEw&qnDev2i8R(lRWDXr&o0@$#ZrCR!t*@eBv{V` zFUVT8&5&WU$GKIW{?6u&-<32uoiZNoTKyr}UHg!r4UeF>L-SSr2Ybq=asN$XIL*1C rg~QdNRynLY#B0CDGp+ryn-4OUFdP@ZZoTg!& +#include + +AttributeView::AttributeView(QWidget* parent, const QString& connection, const QString& modelID, const QString& groupID, const QString& tableName) + : QWidget(parent) + , m_connection(connection) + , m_modelID(modelID) + , m_groupID(groupID) + , m_attributeTable(tableName) +{ + m_tableView = new QTableView(this); + m_attributeTableModel = new AttributeTableModel(this, m_connection, m_modelID, m_groupID, m_attributeTable); + m_tableView->setModel(m_attributeTableModel); + + m_vLayout = new QVBoxLayout(this); + m_vLayout->setSpacing(0); + m_vLayout->setContentsMargins(0, 0, 0, 0); + m_vLayout->addWidget(m_tableView); + this->setLayout(m_vLayout); +} + +AttributeView::~AttributeView() +{} diff --git a/source/customTab.cpp b/source/customTab.cpp new file mode 100644 index 0000000..adcb1da --- /dev/null +++ b/source/customTab.cpp @@ -0,0 +1,62 @@ +#include "customTab.h" +#include "qlabel.h" +#include +#include +#include + +CustomTab::CustomTab(QWidget* parent) + :QWidget(parent) +{ + m_pTitle = new QLabel(this); + + m_IconSize = QSize(16,16); + m_pIconLabel = new QLabel(this); + m_pIconLabel->setMinimumSize(m_IconSize); + m_pIconLabel->setMaximumSize(m_IconSize); + + m_pCloseBtn = new QPushButton(this); + connect(m_pCloseBtn, &QPushButton::clicked, this, &CustomTab::onCloseButtonClicked); + m_pCloseBtn->setMinimumSize(m_IconSize); + m_pCloseBtn->setMaximumSize(m_IconSize); + m_pCloseBtn->setStyleSheet("QPushButton\n" + "{\n" + " border-image: url(:/img/images/btn_close_default.png);\n" + "}\n" + "QPushButton:hover\n" + "{\n" + " border-image: url(:/img/images/btn_close_hover.png);\n" + "}\n" + "QPushButton:pressed\n" + "{\n" + " border-image: url(:/img/images/btn_close_pressed.png);\n" + "}"); + + m_pLayout = new QBoxLayout(QBoxLayout::LeftToRight); + m_pLayout->setContentsMargins(9, 0, 0, 9); + m_pLayout->setSpacing(1); + m_pLayout->addWidget(m_pIconLabel); + m_pLayout->addWidget(m_pTitle); + m_pLayout->addWidget(m_pCloseBtn); + setLayout(m_pLayout); + + m_pCloseBtn->hide(); +} + +CustomTab::~CustomTab() +{ +} + +void CustomTab::enterEvent(QEnterEvent* event) +{ + m_pCloseBtn->show(); +} + +void CustomTab::leaveEvent(QEvent* event) +{ + m_pCloseBtn->hide(); +} + +void CustomTab::onCloseButtonClicked() +{ + emit closeTab(this); +} diff --git a/source/dbBrowser.cpp b/source/dbBrowser.cpp index 47d8b37..7325bee 100644 --- a/source/dbBrowser.cpp +++ b/source/dbBrowser.cpp @@ -1,5 +1,7 @@ #include "dbBrowser.h" #include "ui_dbBrowser.h" +#include "attributeView.h" +#include DatabaseBrowser::DatabaseBrowser(QWidget *parent) : QWidget(parent) @@ -12,3 +14,32 @@ DatabaseBrowser::~DatabaseBrowser() { delete ui; } + +void DatabaseBrowser::addTab_attribute(const QString& connection, ModelAttributeGroup& attributeGroup) +{ + AttributeView* view = new AttributeView(ui->tabWidget, connection, QString::number(attributeGroup.modelID), QString::number(attributeGroup.groupID)); + int index = ui->tabWidget->addTab(view, QIcon(":/img/images/icon_hierarchy.png"), attributeGroup.strGroupName); + //添加自定义按钮 + QPushButton* closeBtn = new QPushButton(""); + closeBtn->setFixedSize(12, 12); + closeBtn->setStyleSheet("QPushButton\n" + "{\n" + " border-image: url(:/img/images/btn_close_default.png);\n" + "}\n" + "QPushButton:hover\n" + "{\n" + " border-image: url(:/img/images/btn_close_hover.png);\n" + "}\n" + "QPushButton:pressed\n" + "{\n" + " border-image: url(:/img/images/btn_close_pressed.png);\n" + "}"); + QTabBar* tabBar = ui->tabWidget->tabBar(); + tabBar->setTabButton(index, QTabBar::RightSide, closeBtn); + + ui->tabWidget->setCurrentIndex(index); +} + +void DatabaseBrowser::closeTab(QWidget* tab) +{ +} diff --git a/source/dbStructureModel.cpp b/source/dbStructureModel.cpp index b8ef3ad..ff19207 100644 --- a/source/dbStructureModel.cpp +++ b/source/dbStructureModel.cpp @@ -179,7 +179,7 @@ void DBStructureModel::removeDataModel(DBStructureNode* modelNode) } return; } - bool result = SqlQueryExecutor::instance().removeMode(connNode->name(), modelID); + bool result = SqlQueryExecutor::instance().removeModel(connNode->name(), modelID); if(!result) { if(m_pMainWindow) diff --git a/source/dbStructureView.cpp b/source/dbStructureView.cpp index 1e276b0..1361ef1 100644 --- a/source/dbStructureView.cpp +++ b/source/dbStructureView.cpp @@ -138,7 +138,7 @@ void DBStructureView::onActionTrigger_removeModel() void DBStructureView::itemDoubleClick(const QModelIndex& index) { DBStructureNode* node = static_cast(index.internalPointer()); - if(node->type() == ConnectionNode ) + if(node->type() == ConnectionNode) { if(!m_curConnection.isEmpty()) //先断掉当前链接 { @@ -152,6 +152,19 @@ void DBStructureView::itemDoubleClick(const QModelIndex& index) m_curConnection = node->name(); } } + else if(node->type() == GroupNode) + { + DBStructureNode* parent = node->parentNode(); + if(parent && parent->type() == TableNode) + { + int modelID = parent->data(Qt::UserRole + NodeDataRole::ID).toInt(); + int groupID = node->data(Qt::UserRole + NodeDataRole::ID).toInt(); + QString modelName = parent->name(); + QString groupName = node->name(); + ModelAttributeGroup attributeGroup(modelID, groupID, modelName, groupName); + emit openAttributeInfo(m_curConnection, attributeGroup); + } + } } void DBStructureView::showContextMenu(const QPoint& pos) diff --git a/source/logger.cpp b/source/logger.cpp index a321f40..6ad8397 100644 --- a/source/logger.cpp +++ b/source/logger.cpp @@ -2,6 +2,7 @@ #include "settings.h" #include #include +#include Logger& Logger::instance() { diff --git a/source/mainwindow.cpp b/source/mainwindow.cpp index 4963305..888eb6a 100644 --- a/source/mainwindow.cpp +++ b/source/mainwindow.cpp @@ -70,6 +70,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::openAttributeInfo, this, &MainWindow::onSIG_openAttributeInfo); ui->layoutDBStructure->addWidget(m_pDBStrutureView); m_pDBStrutureModel = new DBStructureModel(this); m_pDBStrutureModel->setMainWindow(this); @@ -215,3 +216,9 @@ void MainWindow::onSIG_addModel(Model& model) QString connection = m_pDBStrutureView->curConnection(); m_pDBStrutureModel->addDataModel(connection, model); } + +void MainWindow::onSIG_openAttributeInfo(const QString& connection, ModelAttributeGroup& attributeGroup) +{ + if(m_dbBrowser) + m_dbBrowser->addTab_attribute(connection, attributeGroup); +} diff --git a/source/sqlQueryExecutor.cpp b/source/sqlQueryExecutor.cpp index 12a54cc..9a1325b 100644 --- a/source/sqlQueryExecutor.cpp +++ b/source/sqlQueryExecutor.cpp @@ -308,7 +308,7 @@ bool SqlQueryExecutor::modelTypeExistsInDB(const QString& connectionName, const return exists; } -bool SqlQueryExecutor::removeMode(const QString& connectionName, int modelID) +bool SqlQueryExecutor::removeModel(const QString& connectionName, int modelID) { QString strSQL = "DELETE FROM basic.model_type WHERE id = :id"/* + QString::number(modelID)*/; QVariantHash params; @@ -368,3 +368,21 @@ const QString SqlQueryExecutor::getArributeGropuName(const QString& strConnectio return name; } + +int SqlQueryExecutor::getAttributeCount(const QString& strConnectionName, const QString& tableName) +{ + int count = 0; + QString strSQL = QString("SELECT COUNT(*) FROM %1").arg(tableName); + try + { + QSqlQuery query = executeSQL(strConnectionName, strSQL); + if(query.next()) + count = query.value(0).toInt(); + } + catch (const DatabaseException& e) + { + LOG_ERROR("SQL", QString::fromWCharArray(L"获取属性数量失败")); + } + + return count; +} diff --git a/source/tableEditModel.cpp b/source/tableEditModel.cpp new file mode 100644 index 0000000..fae7fe4 --- /dev/null +++ b/source/tableEditModel.cpp @@ -0,0 +1,101 @@ +#include "tableEditModel.h" + +TableEditModel::TableEditModel(QObject *parent, const QSqlDatabase &db, const QStringList &visibleColumns) + : QSqlTableModel(parent, db), m_visibleColumns(visibleColumns) +{ + setEditStrategy(QSqlTableModel::OnManualSubmit); //对编辑数据手动进行提交 + + m_pageSize = 100; + m_currentPage = 1; + m_totalRecords = 0; +} + +TableEditModel::~TableEditModel() +{} + +//重写生成查询的方法 +QString TableEditModel::selectStatement() const +{ + QString originalQuery = QSqlTableModel::selectStatement(); + QString newQuery; + if(m_visibleColumns.isEmpty()) + newQuery = originalQuery; + else + { + int fromInex = originalQuery.indexOf(" FROM "); + QString selectPart = "SELECT " + m_visibleColumns.join(", "); + newQuery = selectPart + originalQuery + selectPart.mid(fromInex); + } + newQuery = newQuery + QString(" LIMIT %1 OFFSET %2").arg(m_pageSize, (m_currentPage - 1) * m_pageSize); + + return newQuery; +} + +QVariant TableEditModel::data(const QModelIndex& index, int role) const +{ + if(!index.isValid()) + return QVariant(); + + if(index.column() == 0) //第一列显示行号 + { + int golbalRow = (m_currentPage - 1) * m_pageSize + index.row(); + switch (role) + { + case Qt::DisplayRole: + { + QString displayRow = QString::number(golbalRow + 1); + if(m_editCache.keys().contains(index.row())) + displayRow = "*" + displayRow; + return displayRow; + } + case Qt::DecorationRole: + return QVariant(); + case Qt::TextAlignmentRole: //行号居中展示 + return Qt::AlignCenter; + default: + return QVariant(); + } + } + else if(role == Qt::UserRole + 100) //先以100来标识数据是否被编辑,在相关代理Delegate类实现中同步进行处理(文字加粗等效果) + return isDirty(index); + else + return QSqlTableModel::data(createIndex(index.row(), index.column() - 1), role); //因为第一列显示行号,所以其它数据列要错位展示 +} + +bool TableEditModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (!index.isValid() || index.column() == 0 || role != Qt::EditRole) //忽略行号列 + return false; + + // if(index.column() == 0) //忽略行号列 + // return QSqlTableModel::setData(createIndex(index.row(), index.column()-1), value, role); + + int row = index.row(); + if (row < 0 || row >= rowCount()) + return false; + + //记录修改到缓存 + if(!m_editCache.contains(row)) + { + EditRecord record; + record.original = QSqlTableModel::record(row); + m_editCache[row] = record; + } + m_editCache[row].modified.setValue(index.column() - 1, value); + + emit dataChanged(index, index, {role}); + return true; +} + +int TableEditModel::columnCount(const QModelIndex &parent) const +{ + return QSqlTableModel::columnCount(parent) + 1; // 原始列数 + 行号列 +} + +Qt::ItemFlags TableEditModel::flags(const QModelIndex &index) const +{ + if(index.column() == 0) //行号列不可编辑 + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + else return QSqlTableModel::flags(this->index(index.row(), index.column() - 1)); +} + diff --git a/source/tableWidgetHoverDelegate.cpp b/source/tableWidgetHoverDelegate.cpp index f572e2f..0dfab31 100644 --- a/source/tableWidgetHoverDelegate.cpp +++ b/source/tableWidgetHoverDelegate.cpp @@ -11,7 +11,7 @@ QTableWidgetHoverDelegate::~QTableWidgetHoverDelegate() void QTableWidgetHoverDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { - if(option.state.testFlag(QStyle::State_MouseOver)) + if(option.state.testFlag(QStyle::State_MouseOver) && m_tableWiget) { QTableWidgetItem* hoveredItem = m_tableWiget->item(index.row(), index.column()); if(hoveredItem) diff --git a/ui/dbBrowser.ui b/ui/dbBrowser.ui index d7808bf..e592fb8 100644 --- a/ui/dbBrowser.ui +++ b/ui/dbBrowser.ui @@ -32,37 +32,11 @@ - 0 + -1 + + + false - - - - :/img/images/icon_hierarchy2.png:/img/images/icon_hierarchy2.png - - - NULL - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - @@ -241,7 +215,7 @@ QPushButton:pressed - 提交更改 + 提交修改 @@ -282,7 +256,7 @@ QPushButton:pressed - 取销更改 + 取销修改