2025-03-24 18:13:06 +08:00
# include "attributeTableModel.h"
2025-04-08 20:02:38 +08:00
# include "attributeNamespace.h"
2025-03-24 18:13:06 +08:00
# include "logger.h"
# include "sqlQueryExecutor.h"
2025-04-29 17:54:44 +08:00
# include <QItemSelectionModel>
2025-03-24 18:13:06 +08:00
2025-03-25 17:58:48 +08:00
AttributeTableModel : : AttributeTableModel ( const ModelAttributeGroup & modelAttributeGroup , QObject * parent , const QString & connection , const QString & tableName )
2025-03-24 18:13:06 +08:00
: QAbstractTableModel ( parent )
, m_connection ( connection )
, m_tableName ( tableName )
2025-03-25 17:58:48 +08:00
, m_modelAttributeGroup ( modelAttributeGroup )
2025-04-29 17:54:44 +08:00
, m_selectionModel ( nullptr )
2025-03-24 18:13:06 +08:00
{
2025-04-29 17:54:44 +08:00
m_filterChars_attributeType = " " ;
2025-03-25 17:58:48 +08:00
m_paginationInfo . entriesPerPage = 100 ;
m_paginationInfo . currentPage = 1 ;
m_paginationInfo . totalEntries = 0 ;
2025-03-24 18:13:06 +08:00
2025-04-08 20:02:38 +08:00
getDataTypesFromDB ( ) ;
2025-03-27 21:01:25 +08:00
iniDisplayField ( ) ;
2025-05-16 18:42:59 +08:00
//refresh(); 改为外部执行刷新,因为刷新时会通过信号同步页码等信息,放在构造函数中信号还未绑定,造成第一次打开为同步
2025-03-24 18:13:06 +08:00
}
AttributeTableModel : : ~ AttributeTableModel ( )
{ }
2025-03-27 14:47:51 +08:00
QModelIndex AttributeTableModel : : index ( int row , int column , const QModelIndex & parent ) const
{
if ( ! hasIndex ( row , column , parent ) )
return QModelIndex ( ) ;
int dataCol = column - 1 ;
2025-04-11 17:14:17 +08:00
if ( dataCol > m_displayField . count ( ) )
2025-03-27 14:47:51 +08:00
return QModelIndex ( ) ;
return createIndex ( row , column ) ;
}
2025-03-24 18:13:06 +08:00
QVariant AttributeTableModel : : data ( const QModelIndex & index , int role ) const
{
if ( ! index . isValid ( ) )
return QVariant ( ) ;
int row = index . row ( ) ;
int col = index . column ( ) ;
2025-03-25 17:58:48 +08:00
int globalRow = ( m_paginationInfo . currentPage - 1 ) * m_paginationInfo . entriesPerPage + row ;
2025-03-24 18:13:06 +08:00
if ( index . column ( ) = = 0 ) //第一列显示行号
{
switch ( role )
{
case Qt : : DisplayRole :
{
2025-03-27 14:47:51 +08:00
QString mark ;
2025-03-24 18:13:06 +08:00
if ( m_modifiedRows . contains ( globalRow ) )
{
switch ( m_modifiedRows [ globalRow ] . state )
{
case Modified :
2025-03-27 14:47:51 +08:00
mark = " * " ;
2025-03-24 18:13:06 +08:00
break ;
case New :
2025-03-27 14:47:51 +08:00
mark = " + " ;
2025-03-24 18:13:06 +08:00
break ;
2025-04-11 17:14:17 +08:00
case New | Modified :
mark = " + " ;
break ;
2025-03-24 18:13:06 +08:00
case Deleted :
2025-03-27 14:47:51 +08:00
mark = " - " ;
2025-03-24 18:13:06 +08:00
break ;
default :
break ;
}
}
2025-03-27 14:47:51 +08:00
return QString : : number ( globalRow + 1 ) + mark ;
2025-03-24 18:13:06 +08:00
}
case Qt : : DecorationRole :
return QVariant ( ) ;
case Qt : : TextAlignmentRole :
return Qt : : AlignCenter ; //行号居中展示
default :
return QVariant ( ) ;
}
}
else
{
int dataCol = col - 1 ;
const RowData & rowData = m_currentPageData [ row ] ;
if ( role = = Qt : : DisplayRole | | role = = Qt : : EditRole )
2025-04-08 20:02:38 +08:00
{
if ( dataCol = = 2 ) //数据类型, 存储的是id, 展示text
{
int dataTypeID = rowData . values . value ( dataCol ) . toInt ( ) ;
const QString & dataTypeText = m_dataTypes . value ( dataTypeID ) . type ;
if ( ! dataTypeText . isEmpty ( ) )
return dataTypeText ;
2025-04-09 12:14:33 +08:00
// else
// return dataTypeID;
2025-04-08 20:02:38 +08:00
}
else
return rowData . values . value ( dataCol ) ;
}
else if ( role = = Qt : : UserRole + AttributeEidt : : EditStatus ) //在相关代理Delegate类实现中同步进行处理( 文字加粗等效果)
2025-04-09 12:14:33 +08:00
{
//return (rowData.state != Clean);
if ( rowData . state = = New ) //新增列,整行加粗
return true ;
else //其它情况只对修改单元格加粗
return rowData . cellModified . value ( dataCol , false ) ;
}
2025-03-24 18:13:06 +08:00
}
return QVariant ( ) ;
}
bool AttributeTableModel : : setData ( const QModelIndex & index , const QVariant & value , int role )
{
if ( role ! = Qt : : EditRole | | index . column ( ) = = 0 )
return false ;
2025-03-27 21:01:25 +08:00
// QModelIndex numberIndex = createIndex(index.row(), 0);
// QString text = numberIndex.data(Qt::DisplayRole).toString();
// qDebug() << text;
// if(text.contains("-")) //删除状态不可编辑
// return false;
2025-03-24 18:13:06 +08:00
int row = index . row ( ) ;
2025-03-25 17:58:48 +08:00
int globalRow = ( m_paginationInfo . currentPage - 1 ) * m_paginationInfo . entriesPerPage + row ;
2025-03-24 18:13:06 +08:00
int dataCol = index . column ( ) - 1 ; //第一列显示了行号
//记录修改
RowData modifiedRow = m_currentPageData [ row ] ;
2025-04-08 20:02:38 +08:00
if ( dataCol = = 2 ) //数据类型
{
QString dataType = value . toString ( ) ;
int id = getDataTypeID ( dataType ) ;
modifiedRow . values [ dataCol ] = id ;
//qDebug() << "dataType-id: " << id;
}
else
modifiedRow . values [ dataCol ] = value ;
2025-04-09 12:14:33 +08:00
modifiedRow . cellModified [ dataCol ] = true ; //标记单元格
2025-04-11 17:14:17 +08:00
const int attributeID = modifiedRow . values . last ( ) . toInt ( ) ;
if ( attributeID = = - 1 ) //纯新建
modifiedRow . state = ( modifiedRow . state = = New ) ? New : Modified ;
else
modifiedRow . state = ( modifiedRow . state = = New ) ? modifiedRow . state | = Modified : Modified ; //新建时从已有数据进行的加载,然后再次编辑就会变为叠加态
2025-03-24 18:13:06 +08:00
m_modifiedRows [ globalRow ] = modifiedRow ;
m_currentPageData [ row ] = modifiedRow ;
2025-04-08 20:02:38 +08:00
emit dataChanged ( index , index , { role , Qt : : UserRole + AttributeEidt : : EditStatus } ) ;
2025-04-25 11:49:03 +08:00
emit syncDataStatus ( dataHasbeenModified ( ) , m_paginationInfo ) ;
2025-03-24 18:13:06 +08:00
return true ;
}
QVariant AttributeTableModel : : headerData ( int section , Qt : : Orientation orientation , int role ) const
{
if ( orientation = = Qt : : Horizontal & & role = = Qt : : DisplayRole )
{
if ( section = = 0 )
return role = = Qt : : DisplayRole ? " No. " : QVariant ( ) ;
else
{
2025-03-28 17:40:59 +08:00
QString headerText = m_displayField . value ( section - 1 ) . displayName ;
if ( ! m_displayField . value ( section - 1 ) . dataType . isEmpty ( ) )
headerText = headerText + " \n " + m_displayField . value ( section - 1 ) . dataType ;
return headerText ;
2025-03-24 18:13:06 +08:00
}
}
return QAbstractTableModel : : headerData ( section , orientation , role ) ;
}
int AttributeTableModel : : rowCount ( const QModelIndex & parent ) const
{
return m_currentPageData . count ( ) ;
}
int AttributeTableModel : : columnCount ( const QModelIndex & ) const
{
2025-03-27 21:01:25 +08:00
return m_displayField . isEmpty ( ) ? 0 : m_displayField . count ( ) + 1 ;
2025-03-24 18:13:06 +08:00
}
Qt : : ItemFlags AttributeTableModel : : flags ( const QModelIndex & index ) const
{
Qt : : ItemFlags flags = QAbstractTableModel : : flags ( index ) ;
2025-04-28 14:25:45 +08:00
QModelIndex numberIndex = createIndex ( index . row ( ) , 0 ) ;
QString text = numberIndex . data ( Qt : : DisplayRole ) . toString ( ) ;
2025-04-11 17:14:17 +08:00
2025-04-28 14:25:45 +08:00
if ( index . column ( ) ! = 0 & & ! text . contains ( " - " ) ) //行号列和处于删除状态的item不能编辑
flags = flags | Qt : : ItemIsEditable ;
return flags ;
}
2025-04-29 17:54:44 +08:00
void AttributeTableModel : : setSelectionModel ( QItemSelectionModel * sm )
{
m_selectionModel = sm ;
connect ( m_selectionModel , & QItemSelectionModel : : selectionChanged , this , [ this ] {
//刷新整个区域
QModelIndex topLeft = createIndex ( 0 , 0 ) ;
QModelIndex bottomRight = createIndex ( rowCount ( ) - 1 , columnCount ( ) - 1 ) ;
emit dataChanged ( topLeft , bottomRight ) ;
} ) ;
}
2025-04-28 14:25:45 +08:00
void AttributeTableModel : : setModelAttributeGroup ( const ModelAttributeGroup & modelAttributeGroup )
{
m_modelAttributeGroup = modelAttributeGroup ;
//重新刷新
m_paginationInfo . currentPage = 1 ;
forceRefresh ( ) ;
2025-04-11 17:14:17 +08:00
}
bool AttributeTableModel : : attributeTypeExistsInCurrentGroup ( int id , const QString & type )
{
//先查找内存数据
for ( RowData rowData : m_currentPageData )
{
if ( rowData . values [ 0 ] = = type )
return true ;
}
//再从数据库中查找,因为内存只存储当前页的数据
if ( id ! = - 1 ) //说明是之前创建过的属性(数据库中已存在)
return SqlQueryExecutor : : instance ( ) . attributeTypeUseByModelGroup ( m_connection , id , m_modelAttributeGroup . modelID , m_modelAttributeGroup . groupID ) ;
return false ;
}
void AttributeTableModel : : updateRowThroughExisitingAttribute ( int row , int attributeID )
{
//qDebug() << "row:" << row << " attributeID:" << attributeID;
QStringList columns ;
for ( int i = 0 ; i < m_displayField . count ( ) ; i + + )
columns < < m_displayField . at ( i ) . originalName ;
Attribute attribute ;
attribute . id = attributeID ;
if ( SqlQueryExecutor : : instance ( ) . getAttributeInfo ( m_connection , columns . join ( " , " ) , attribute ) )
{
RowData updateRow = m_currentPageData [ row ] ;
//updateRow.values.resize(m_displayField.count() + 1);
updateRow . values [ 0 ] = attribute . type ;
updateRow . values [ 1 ] = attribute . name ;
updateRow . values [ 2 ] = attribute . dataTypeID ;
updateRow . values [ 3 ] = attribute . dataLength ;
updateRow . values [ 4 ] = attribute . defaultValue ;
2025-04-27 16:24:13 +08:00
updateRow . values [ 5 ] = attribute . isVisible ;
updateRow . values [ 6 ] = attribute . id ; //将id存入最后, 不做显示, 删除或者修改数据的时候会用到
2025-04-11 17:14:17 +08:00
for ( int i = 0 ; i < m_displayField . count ( ) ; i + + )
updateRow . cellModified [ i ] = true ; //标记单元格
updateRow . state = ( updateRow . state = = New ) ? New : Modified ;
m_currentPageData [ row ] = updateRow ;
int globalRow = ( m_paginationInfo . currentPage - 1 ) * m_paginationInfo . entriesPerPage + row ;
m_modifiedRows [ globalRow ] = updateRow ;
QModelIndex topLeft = index ( row , 1 , QModelIndex ( ) ) ;
QModelIndex bottomRight = index ( row , m_displayField . count ( ) , QModelIndex ( ) ) ;
emit dataChanged ( topLeft , bottomRight ) ;
}
2025-03-24 18:13:06 +08:00
}
2025-03-27 21:01:25 +08:00
void AttributeTableModel : : iniDisplayField ( )
{
FieldInfo field1 ;
field1 . originalName = " attribute " ;
field1 . displayName = QString : : fromWCharArray ( L " 属性类别 " ) ;
2025-03-31 16:01:49 +08:00
//field1.dataType = "character varying(128)";
2025-03-27 21:01:25 +08:00
m_displayField . append ( field1 ) ;
FieldInfo field2 ;
field2 . originalName = " attribute_name " ;
field2 . displayName = QString : : fromWCharArray ( L " 属性名称 " ) ;
2025-03-31 16:01:49 +08:00
//field2.dataType = "character varying(64)";
2025-03-27 21:01:25 +08:00
m_displayField . append ( field2 ) ;
FieldInfo field3 ;
field3 . originalName = " data_type_id " ;
field3 . displayName = QString : : fromWCharArray ( L " 数据类型 " ) ;
2025-04-08 20:02:38 +08:00
field3 . dataType = " character varying(64) " ;
2025-03-27 21:01:25 +08:00
m_displayField . append ( field3 ) ;
FieldInfo field4 ;
field4 . originalName = " length_precision " ;
2025-03-31 16:01:49 +08:00
field4 . displayName = QString : : fromWCharArray ( L " 数据长度 " ) ;
//field4.dataType = "integer";
2025-03-27 21:01:25 +08:00
m_displayField . append ( field4 ) ;
FieldInfo field5 ;
field5 . originalName = " default_value " ;
field5 . displayName = QString : : fromWCharArray ( L " 默认值 " ) ;
2025-03-31 16:01:49 +08:00
//field5.dataType = "character varying(64)";
2025-03-27 21:01:25 +08:00
m_displayField . append ( field5 ) ;
2025-03-31 16:01:49 +08:00
2025-04-27 16:24:13 +08:00
FieldInfo field6 ;
field6 . originalName = " is_visible " ;
field6 . displayName = QString : : fromWCharArray ( L " 可见性 " ) ;
//field6.dataType = "smallint";
m_displayField . append ( field6 ) ;
2025-03-31 16:01:49 +08:00
QHash < QString , QString > fieldType = SqlQueryExecutor : : instance ( ) . getFiledType ( m_connection , " attribute " , " basic " ) ;
for ( int i = 0 ; i < m_displayField . count ( ) ; i + + )
{
QString strFiled = m_displayField . at ( i ) . originalName ;
2025-04-08 20:02:38 +08:00
if ( strFiled = = " data_type_id " ) //数据类型以字符串的方式显示
continue ;
2025-03-31 16:01:49 +08:00
m_displayField [ i ] . dataType = fieldType . value ( strFiled ) ;
}
}
2025-04-08 20:02:38 +08:00
void AttributeTableModel : : getDataTypesFromDB ( )
2025-03-31 16:01:49 +08:00
{
QString strSQL = " SELECT * FROM basic.data_type ORDER BY id ASC " ;
try
{
QSqlQuery query = SqlQueryExecutor : : instance ( ) . executeSQL ( m_connection , strSQL ) ;
while ( query . next ( ) )
{
DataType dataType ;
dataType . id = query . value ( 0 ) . toInt ( ) ;
dataType . type = query . value ( 1 ) . toString ( ) ;
dataType . db = query . value ( 2 ) . toString ( ) ;
m_dataTypes . insert ( dataType . id , dataType ) ;
2025-04-08 20:02:38 +08:00
m_reversalDataTypes . insert ( dataType . type , dataType . id ) ;
2025-03-31 16:01:49 +08:00
}
}
catch ( const DatabaseException & e )
{
LOG_ERROR ( " SQL " , QString : : fromWCharArray ( L " 获取数据类型失败 " ) ) ;
}
2025-03-27 21:01:25 +08:00
}
2025-04-08 20:02:38 +08:00
int AttributeTableModel : : getDataTypeID ( const QString & type )
{
return m_reversalDataTypes . value ( type , 11 ) ; //11是VARCHAR的id, 作为默认值
}
2025-03-24 18:13:06 +08:00
void AttributeTableModel : : loadPageData ( )
{
2025-03-26 15:57:08 +08:00
m_currentPageData . clear ( ) ;
2025-04-01 16:45:30 +08:00
/*if (m_tableName.isEmpty())
2025-03-24 18:13:06 +08:00
{
LOG_ERROR ( " DB " , QString ( " Attribute table name is empty, load data failed " ) ) ;
return ;
2025-04-01 16:45:30 +08:00
} */
2025-03-24 18:13:06 +08:00
beginResetModel ( ) ;
2025-04-11 17:14:17 +08:00
QStringList columns ;
for ( int i = 0 ; i < m_displayField . count ( ) ; i + + )
columns < < m_displayField . at ( i ) . originalName ;
2025-04-01 16:45:30 +08:00
2025-04-28 14:25:45 +08:00
if ( m_modelAttributeGroup . modelID = = - 1 ) //表示当前加载数据对象是所有属性
2025-04-11 17:14:17 +08:00
{
columns . append ( " id " ) ; //将id放到最后, 和按照具体模型、具体属性组读取数据方式时逻辑统一, 具体见下面分支逻辑
2025-05-19 20:13:38 +08:00
QString strSQL = QString ( " SELECT %1 FROM basic.attribute WHERE attribute LIKE '%%2%' ORDER BY id ASC LIMIT %3 OFFSET %4 " )
2025-04-11 17:14:17 +08:00
. arg ( columns . join ( " , " ) )
2025-05-19 20:13:38 +08:00
. arg ( m_filterChars_attributeType )
2025-04-11 17:14:17 +08:00
. arg ( m_paginationInfo . entriesPerPage )
. arg ( ( m_paginationInfo . currentPage - 1 ) * m_paginationInfo . entriesPerPage ) ;
try
2025-03-24 18:13:06 +08:00
{
2025-04-11 17:14:17 +08:00
QSqlQuery query = SqlQueryExecutor : : instance ( ) . executeSQL ( m_connection , strSQL ) ;
while ( query . next ( ) )
2025-03-26 15:57:08 +08:00
{
2025-05-19 20:13:38 +08:00
// QString type = query.value(0).toString();
// if(!m_filterChars_attributeType.isEmpty() && !type.contains(m_filterChars_attributeType))
// continue;
2025-04-29 17:54:44 +08:00
2025-04-01 16:45:30 +08:00
RowData data ;
2025-04-11 17:14:17 +08:00
for ( int i = 0 ; i < columns . count ( ) ; i + + )
data . values . append ( query . value ( i ) ) ;
2025-04-01 16:45:30 +08:00
m_currentPageData . append ( data ) ;
2025-03-26 15:57:08 +08:00
}
2025-03-24 18:13:06 +08:00
}
2025-04-11 17:14:17 +08:00
catch ( const DatabaseException & e )
{
LOG_ERROR ( " SQL " , QString : : fromWCharArray ( L " 获取属性信息失败(所有属性)。 " ) ) ;
}
2025-03-24 18:13:06 +08:00
}
2025-04-11 17:14:17 +08:00
else //按具体模型的具体属性组读取数据
2025-03-24 18:13:06 +08:00
{
2025-04-22 17:45:37 +08:00
QString strSQL = " " ;
bool isPublicGroup = SqlQueryExecutor : : instance ( ) . isPublicAttributeGroup ( m_connection , m_modelAttributeGroup . groupID ) ;
if ( isPublicGroup )
2025-05-21 11:31:40 +08:00
/*strSQL = QString("SELECT attribute_id FROM basic.model_attribute_public WHERE attribute_group_id = %1 ORDER BY id ASC LIMIT %2 OFFSET %3")
2025-04-22 17:45:37 +08:00
. arg ( m_modelAttributeGroup . groupID )
. arg ( m_paginationInfo . entriesPerPage )
2025-05-21 11:31:40 +08:00
. arg ( ( m_paginationInfo . currentPage - 1 ) * m_paginationInfo . entriesPerPage ) ; */
strSQL = QString ( " SELECT attribute_id FROM basic.model_attribute_public AS map "
" INNER JOIN basic.attribute AS a ON map.attribute_id = a.id "
" WHERE attribute_group_id = %1 "
" AND a.attribute LIKE '%%2%' "
" ORDER BY map.id ASC LIMIT %3 OFFSET %4 " )
. arg ( m_modelAttributeGroup . groupID )
. arg ( m_filterChars_attributeType )
. arg ( m_paginationInfo . entriesPerPage )
2025-04-22 17:45:37 +08:00
. arg ( ( m_paginationInfo . currentPage - 1 ) * m_paginationInfo . entriesPerPage ) ;
2025-04-29 17:54:44 +08:00
//利用短路机制, 当attribute_group_id!=-1时, 括号整体为false, 需要进行内部条件判断, =-1时, 整体为true, 忽略整体, 也就忽略了attribute_group_id的条件判断
2025-05-21 11:31:40 +08:00
else
/*strSQL = QString("SELECT attribute_id FROM basic.model_attribute WHERE model_type_id = %1 AND (attribute_group_id = %2 OR %2 = -1) ORDER BY id ASC LIMIT %3 OFFSET %4")
2025-04-22 17:45:37 +08:00
. arg ( m_modelAttributeGroup . modelID )
. arg ( m_modelAttributeGroup . groupID )
. arg ( m_paginationInfo . entriesPerPage )
2025-05-21 11:31:40 +08:00
. arg ( ( m_paginationInfo . currentPage - 1 ) * m_paginationInfo . entriesPerPage ) ; */
strSQL = QString ( " SELECT attribute_id FROM basic.model_attribute AS map "
" INNER JOIN basic.attribute AS a ON map.attribute_id = a.id "
" WHERE model_type_id = %1 "
" AND (attribute_group_id = %2 OR %2 = -1) "
" AND a.attribute LIKE '%%3%' "
" ORDER BY map.id ASC LIMIT %4 OFFSET %5 " )
. arg ( m_modelAttributeGroup . modelID )
. arg ( m_modelAttributeGroup . groupID )
. arg ( m_filterChars_attributeType )
. arg ( m_paginationInfo . entriesPerPage )
. arg ( ( m_paginationInfo . currentPage - 1 ) * m_paginationInfo . entriesPerPage ) ;
2025-04-11 17:14:17 +08:00
try
{
QSqlQuery query = SqlQueryExecutor : : instance ( ) . executeSQL ( m_connection , strSQL ) ;
while ( query . next ( ) )
{
Attribute attribute ;
attribute . id = query . value ( 0 ) . toInt ( ) ;
if ( SqlQueryExecutor : : instance ( ) . getAttributeInfo ( m_connection , columns . join ( " , " ) , attribute ) )
{
2025-05-21 11:31:40 +08:00
// if(!m_filterChars_attributeType.isEmpty() && !attribute.type.contains(m_filterChars_attributeType))
// continue;
2025-04-29 17:54:44 +08:00
2025-04-11 17:14:17 +08:00
RowData data ;
data . values . append ( attribute . type ) ;
data . values . append ( attribute . name ) ;
data . values . append ( attribute . dataTypeID ) ;
data . values . append ( attribute . dataLength ) ;
data . values . append ( attribute . defaultValue ) ;
2025-04-27 16:24:13 +08:00
data . values . append ( attribute . isVisible ) ;
2025-04-11 17:14:17 +08:00
data . values . append ( attribute . id ) ; //将id存入最后, 不做显示, 删除或者修改数据的时候会用到
m_currentPageData . append ( data ) ;
}
}
}
catch ( const DatabaseException & e )
{
LOG_ERROR ( " SQL " , QString : : fromWCharArray ( L " 获取属性信息失败。modelID:%1, groupID:%2 " ) . arg ( m_modelAttributeGroup . modelID , m_modelAttributeGroup . groupID ) ) ;
}
2025-03-24 18:13:06 +08:00
}
endResetModel ( ) ;
}
2025-03-26 15:57:08 +08:00
void AttributeTableModel : : setPageSize ( int size )
{
if ( m_paginationInfo . entriesPerPage ! = size & & size > 0 )
{
m_paginationInfo . entriesPerPage = size ;
refresh ( ) ;
}
}
int AttributeTableModel : : pageSize ( ) const
{
return m_paginationInfo . entriesPerPage ;
}
2025-04-25 11:49:03 +08:00
bool AttributeTableModel : : setCurrentPage ( int page )
2025-03-26 15:57:08 +08:00
{
if ( m_paginationInfo . currentPage ! = page & & page > 0 & & page < = totalPages ( ) )
{
m_paginationInfo . currentPage = page ;
refresh ( ) ;
2025-04-25 11:49:03 +08:00
return true ;
2025-03-26 15:57:08 +08:00
}
2025-04-25 11:49:03 +08:00
return false ;
2025-03-26 15:57:08 +08:00
}
int AttributeTableModel : : currentPage ( ) const
{
return m_paginationInfo . currentPage ;
}
int AttributeTableModel : : totalPages ( ) const
{
return qCeil ( static_cast < qreal > ( m_paginationInfo . totalEntries ) / m_paginationInfo . entriesPerPage ) ;
}
void AttributeTableModel : : previousPage ( )
{
2025-04-29 17:54:44 +08:00
if ( m_paginationInfo . currentPage = = 1 )
2025-03-26 15:57:08 +08:00
return ;
2025-05-19 11:04:46 +08:00
int page = m_paginationInfo . currentPage ;
setCurrentPage ( - - page ) ;
2025-03-26 15:57:08 +08:00
}
void AttributeTableModel : : nextPage ( )
{
2025-04-29 17:54:44 +08:00
if ( m_paginationInfo . currentPage = = totalPages ( ) )
2025-03-26 15:57:08 +08:00
return ;
2025-05-19 11:04:46 +08:00
int page = m_paginationInfo . currentPage ;
setCurrentPage ( + + page ) ;
2025-03-26 15:57:08 +08:00
}
void AttributeTableModel : : firstPage ( )
{
2025-04-29 17:54:44 +08:00
if ( m_paginationInfo . currentPage = = 1 )
2025-03-26 15:57:08 +08:00
return ;
setCurrentPage ( 1 ) ;
}
void AttributeTableModel : : lastPage ( )
{
2025-04-29 17:54:44 +08:00
if ( m_paginationInfo . currentPage = = totalPages ( ) )
2025-03-26 15:57:08 +08:00
return ;
setCurrentPage ( totalPages ( ) ) ;
}
2025-03-24 18:13:06 +08:00
void AttributeTableModel : : updateTotalCount ( )
{
2025-04-01 16:45:30 +08:00
/*if (m_tableName.isEmpty())
2025-03-24 18:13:06 +08:00
{
LOG_ERROR ( " SQL " , QString : : fromWCharArray ( L " 属性表名称为空,获取属性数量失败 " ) ) ;
return ;
2025-04-01 16:45:30 +08:00
} */
2025-03-24 18:13:06 +08:00
2025-04-28 14:25:45 +08:00
if ( m_modelAttributeGroup . modelID = = - 1 )
2025-05-19 20:13:38 +08:00
m_paginationInfo . totalEntries = SqlQueryExecutor : : instance ( ) . getAllAttributeCount ( m_connection , m_filterChars_attributeType ) ;
2025-04-11 17:14:17 +08:00
else
2025-05-21 11:31:40 +08:00
m_paginationInfo . totalEntries = SqlQueryExecutor : : instance ( ) . getAttributeCount ( m_connection , m_modelAttributeGroup . modelID , m_modelAttributeGroup . groupID , m_filterChars_attributeType ) ;
2025-05-16 10:42:36 +08:00
m_paginationInfo . totalPages = totalPages ( ) ;
2025-03-24 18:13:06 +08:00
}
2025-03-25 20:53:15 +08:00
2025-04-11 17:14:17 +08:00
QList < AttributeTableModel : : RowData > AttributeTableModel : : filterRowsByEditState ( EditStateFlag state )
2025-04-01 14:37:41 +08:00
{
QList < RowData > result ;
for ( auto it = m_modifiedRows . begin ( ) ; it ! = m_modifiedRows . end ( ) ; it + + )
{
2025-04-11 17:14:17 +08:00
if ( it . value ( ) . state . testFlag ( state ) )
2025-04-01 14:37:41 +08:00
result . append ( it . value ( ) ) ;
}
return result ;
}
2025-04-01 16:45:30 +08:00
/*void AttributeTableModel::setTable(const QString& tableName)
2025-03-26 15:57:08 +08:00
{
if ( m_tableName = = tableName )
return ;
m_tableName = tableName ;
m_modifiedRows . clear ( ) ;
refresh ( ) ;
2025-04-01 16:45:30 +08:00
} */
2025-03-26 15:57:08 +08:00
void AttributeTableModel : : refresh ( )
{
2025-04-25 11:49:03 +08:00
if ( dataHasbeenModified ( ) )
2025-03-26 15:57:08 +08:00
{
emit showMessage ( type_question , QString : : fromWCharArray ( L " 提示 " ) ,
2025-04-25 11:49:03 +08:00
QString : : fromWCharArray ( L " 有编辑数据还未提交,确认要放弃吗? " ) ) ;
2025-04-02 15:57:00 +08:00
if ( g_msgDlgBtn = = btn_No )
return ;
2025-03-26 15:57:08 +08:00
}
2025-04-02 15:57:00 +08:00
m_modifiedRows . clear ( ) ;
2025-03-26 15:57:08 +08:00
loadPageData ( ) ;
updateTotalCount ( ) ;
2025-04-25 11:49:03 +08:00
emit syncDataStatus ( dataHasbeenModified ( ) , m_paginationInfo ) ;
}
void AttributeTableModel : : forceRefresh ( )
{
m_modifiedRows . clear ( ) ;
loadPageData ( ) ;
updateTotalCount ( ) ;
emit syncDataStatus ( dataHasbeenModified ( ) , m_paginationInfo ) ;
2025-03-26 15:57:08 +08:00
}
2025-03-27 14:47:51 +08:00
void AttributeTableModel : : insertRecord ( int row )
{
2025-05-06 17:51:03 +08:00
if ( row < 0 /*|| row > rowCount()*/ )
2025-03-27 14:47:51 +08:00
return ;
RowData newRow ;
newRow . state = New ;
2025-04-11 17:14:17 +08:00
newRow . values . resize ( m_displayField . count ( ) + 1 ) ; //多出一个位置给id
newRow . values . last ( ) = - 1 ;
2025-04-09 12:14:33 +08:00
//newRow.values[2] = 11;
2025-03-27 14:47:51 +08:00
int globalRow = ( m_paginationInfo . currentPage - 1 ) * m_paginationInfo . entriesPerPage + row ;
m_modifiedRows [ globalRow ] = newRow ;
beginInsertRows ( QModelIndex ( ) , row , row ) ;
m_currentPageData . insert ( row , newRow ) ;
endInsertRows ( ) ;
}
2025-05-08 09:30:47 +08:00
void AttributeTableModel : : addRecords ( QVector < QVector < QVariant > > records )
2025-05-07 17:34:27 +08:00
{
2025-05-08 09:30:47 +08:00
QVector < QVector < QVariant > > validRecords ;
2025-05-07 17:34:27 +08:00
//首先过滤掉已经存在记录
2025-05-08 09:30:47 +08:00
for ( const QVector < QVariant > & record : records )
2025-05-07 17:34:27 +08:00
{
2025-05-08 09:30:47 +08:00
int id = record . last ( ) . toInt ( ) ; //目前该函数的数据源都来‘属性选择器’(都是已创建好的属性)
QString type = record . value ( 0 ) . toString ( ) ;
2025-05-07 17:34:27 +08:00
bool existed = attributeTypeExistsInCurrentGroup ( id , type ) ;
if ( ! existed )
validRecords . append ( record ) ;
}
if ( validRecords . count ( ) = = 0 )
return ;
2025-05-08 09:30:47 +08:00
beginInsertRows ( QModelIndex ( ) , rowCount ( ) , rowCount ( ) + validRecords . count ( ) - 1 ) ;
2025-05-07 17:34:27 +08:00
int row = m_currentPageData . count ( ) ;
2025-05-08 09:30:47 +08:00
for ( const QVector < QVariant > & record : validRecords )
2025-05-07 17:34:27 +08:00
{
RowData newRow ;
newRow . state = New ;
2025-05-08 09:30:47 +08:00
newRow . values = record ;
2025-05-07 17:34:27 +08:00
int globalRow = ( m_paginationInfo . currentPage - 1 ) * m_paginationInfo . entriesPerPage + row ;
m_modifiedRows [ globalRow ] = newRow ;
m_currentPageData . insert ( row , newRow ) ;
row + + ;
}
endInsertRows ( ) ;
}
2025-04-29 17:54:44 +08:00
void AttributeTableModel : : removeRecord ( )
{
//以第一列也就是编号列是否选中为判断依据,找出所有被选中的行
for ( int row = 0 ; row < rowCount ( ) ; row + + )
{
QModelIndex numberIndex = createIndex ( row , 0 ) ;
if ( m_selectionModel & & m_selectionModel - > isSelected ( numberIndex ) )
{
if ( removeRecord ( row ) )
row - - ;
}
}
}
bool AttributeTableModel : : removeRecord ( int row )
2025-03-26 15:57:08 +08:00
{
2025-03-27 14:47:51 +08:00
if ( row < 0 | | row > rowCount ( ) )
2025-04-29 17:54:44 +08:00
return false ;
2025-03-27 14:47:51 +08:00
2025-04-02 10:44:52 +08:00
/*emit showMessage(type_question, QString::fromWCharArray(L"提示"),
2025-03-27 14:47:51 +08:00
QString : : fromWCharArray ( L " 确认要删除该记录吗? " ) ) ;
if ( g_msgDlgBtn = = btn_No )
2025-04-02 10:44:52 +08:00
return ; */
2025-03-27 14:47:51 +08:00
int globalRow = ( m_paginationInfo . currentPage - 1 ) * m_paginationInfo . entriesPerPage + row ;
2025-03-31 16:01:49 +08:00
if ( m_currentPageData . at ( row ) . state = = New ) //新添加未提交的记录,直接删除
2025-03-27 14:47:51 +08:00
{
2025-03-27 21:01:25 +08:00
beginRemoveRows ( QModelIndex ( ) , row , row ) ;
2025-03-27 14:47:51 +08:00
m_modifiedRows . remove ( globalRow ) ;
2025-03-27 21:01:25 +08:00
m_currentPageData . removeAt ( row ) ;
endRemoveRows ( ) ;
2025-04-29 17:54:44 +08:00
return true ;
2025-03-27 14:47:51 +08:00
}
2025-03-31 16:01:49 +08:00
else //整行画红线进行标记
2025-03-27 14:47:51 +08:00
{
m_currentPageData [ row ] . state = Deleted ;
m_modifiedRows [ globalRow ] = m_currentPageData [ row ] ;
2025-03-27 21:01:25 +08:00
m_modifiedRows [ globalRow ] . state = Deleted ;
QModelIndex topLeft = createIndex ( row , 0 ) ;
QModelIndex bottomRight = createIndex ( row , columnCount ( ) - 1 ) ;
emit dataChanged ( topLeft , bottomRight , { Qt : : DisplayRole } ) ;
2025-04-29 17:54:44 +08:00
return false ;
2025-03-27 14:47:51 +08:00
}
2025-03-26 15:57:08 +08:00
}
2025-04-01 14:37:41 +08:00
void AttributeTableModel : : submitChanges ( )
{
QList < RowData > insertRows = filterRowsByEditState ( New ) ;
2025-04-02 10:44:52 +08:00
bool insertCompleted = false ;
QList < RowData > deleteRows = filterRowsByEditState ( Deleted ) ;
bool deleteCompleted = false ;
2025-04-02 14:58:42 +08:00
QList < RowData > updateRows = filterRowsByEditState ( Modified ) ;
bool updateCompleted = false ;
2025-04-01 14:37:41 +08:00
2025-04-02 14:58:42 +08:00
//插入操作
2025-04-01 14:37:41 +08:00
if ( ! insertRows . isEmpty ( ) )
{
QList < Attribute > insertAttributes ;
for ( const RowData & rowData : insertRows )
{
QString type = rowData . values . value ( 0 ) . toString ( ) ;
QString name = rowData . values . value ( 1 ) . toString ( ) ;
if ( type . isEmpty ( ) | | name . isEmpty ( ) )
continue ;
int dataTypeID = rowData . values . value ( 2 ) . toInt ( ) ;
int dataLength = - 1 ;
if ( rowData . values . value ( 3 ) . isValid ( ) )
dataLength = rowData . values . value ( 3 ) . toInt ( ) ;
2025-04-02 10:44:52 +08:00
QString defaultValue = " null " ;
if ( rowData . values . value ( 4 ) . isValid ( ) )
defaultValue = rowData . values . value ( 4 ) . toString ( ) ;
2025-04-27 16:24:13 +08:00
int isVisible = rowData . values . value ( 5 ) . toInt ( ) ;
2025-04-02 14:58:42 +08:00
2025-04-11 17:14:17 +08:00
int id = - 1 ;
if ( rowData . values . size ( ) = = m_displayField . count ( ) + 1 )
id = rowData . values . value ( m_displayField . count ( ) ) . toInt ( ) ;
2025-04-27 16:24:13 +08:00
insertAttributes . emplace_back ( id , name , type , dataTypeID , dataLength , defaultValue , isVisible ) ;
2025-04-01 14:37:41 +08:00
}
2025-04-02 10:44:52 +08:00
insertCompleted = SqlQueryExecutor : : instance ( ) . batchInsertAttributes ( m_connection , m_modelAttributeGroup . modelID , m_modelAttributeGroup . groupID , insertAttributes ) ;
2025-04-01 14:37:41 +08:00
}
2025-04-02 14:58:42 +08:00
//删除操作
2025-04-02 10:44:52 +08:00
if ( ! deleteRows . isEmpty ( ) )
2025-04-01 14:37:41 +08:00
{
2025-04-02 10:44:52 +08:00
QList < int > deleteAttributes ;
for ( const RowData & rowData : deleteRows )
{
if ( rowData . values . count ( ) ! = m_displayField . count ( ) + 1 ) //loadPageData时, 会把属性id放到valuse的最后, 并且不做展示
continue ;
deleteAttributes . push_back ( rowData . values . last ( ) . toInt ( ) ) ;
}
deleteCompleted = SqlQueryExecutor : : instance ( ) . batchDeleteAttributes ( m_connection , m_modelAttributeGroup . modelID , m_modelAttributeGroup . groupID , deleteAttributes ) ;
2025-04-01 14:37:41 +08:00
}
2025-04-02 14:58:42 +08:00
//更新操作
if ( ! updateRows . isEmpty ( ) )
{
QList < Attribute > updateAttributes ;
for ( const RowData & rowData : updateRows )
{
if ( rowData . values . count ( ) ! = m_displayField . count ( ) + 1 ) //loadPageData时, 会把属性id放到valuse的最后, 并且不做展示
continue ;
int id = rowData . values . last ( ) . toInt ( ) ;
QString type = rowData . values . value ( 0 ) . toString ( ) ;
QString name = rowData . values . value ( 1 ) . toString ( ) ;
int dataTypeID = rowData . values . value ( 2 ) . toInt ( ) ;
int dataLength = - 1 ;
if ( rowData . values . value ( 3 ) . isValid ( ) )
dataLength = rowData . values . value ( 3 ) . toInt ( ) ;
QString defaultValue = " null " ;
if ( rowData . values . value ( 4 ) . isValid ( ) )
defaultValue = rowData . values . value ( 4 ) . toString ( ) ;
2025-04-27 16:24:13 +08:00
int isVisible = rowData . values . value ( 5 ) . toInt ( ) ;
2025-04-02 14:58:42 +08:00
2025-04-27 16:24:13 +08:00
updateAttributes . emplace_back ( id , name , type , dataTypeID , dataLength , defaultValue , isVisible ) ;
2025-04-02 14:58:42 +08:00
}
updateCompleted = SqlQueryExecutor : : instance ( ) . batchUpdateAttributes ( m_connection , m_modelAttributeGroup . modelID , m_modelAttributeGroup . groupID , updateAttributes ) ;
}
2025-04-02 10:44:52 +08:00
2025-04-02 14:58:42 +08:00
if ( ( ! insertRows . isEmpty ( ) & & ! insertCompleted )
& & ( ! deleteRows . isEmpty ( ) & & ! deleteCompleted )
& & ( ! updateRows . isEmpty ( ) & & ! updateCompleted ) )
2025-04-02 10:44:52 +08:00
{
2025-04-01 14:37:41 +08:00
emit showMessage ( type_warning , QString : : fromWCharArray ( L " 错误 " ) , QString : : fromWCharArray ( L " 数据提交失败,详情可查看日志文件 " ) ) ;
2025-04-02 10:44:52 +08:00
}
m_modifiedRows . clear ( ) ;
refresh ( ) ;
2025-04-01 14:37:41 +08:00
}
2025-04-02 15:57:00 +08:00
void AttributeTableModel : : cancleChanges ( )
{
2025-04-25 11:49:03 +08:00
if ( ! dataHasbeenModified ( ) )
2025-04-02 15:57:00 +08:00
return ;
m_modifiedRows . clear ( ) ;
loadPageData ( ) ;
updateTotalCount ( ) ;
2025-04-25 11:49:03 +08:00
emit syncDataStatus ( dataHasbeenModified ( ) , m_paginationInfo ) ;
2025-04-02 15:57:00 +08:00
}
2025-05-08 09:30:47 +08:00
QVector < QVector < QVariant > > AttributeTableModel : : getSelectedRowData ( )
2025-05-07 17:34:27 +08:00
{
2025-05-08 09:30:47 +08:00
QVector < QVector < QVariant > > result ;
2025-05-07 17:34:27 +08:00
for ( int row = 0 ; row < rowCount ( ) ; row + + )
{
QModelIndex numberIndex = createIndex ( row , 0 ) ;
if ( m_selectionModel & & m_selectionModel - > isSelected ( numberIndex ) )
2025-05-08 09:30:47 +08:00
result . append ( m_currentPageData . at ( row ) . values ) ;
2025-05-07 17:34:27 +08:00
}
return result ;
}
2025-03-25 20:53:15 +08:00
void AttributeTableModel : : triggerSyncSignal ( )
{
2025-04-25 11:49:03 +08:00
emit syncDataStatus ( dataHasbeenModified ( ) , m_paginationInfo ) ;
2025-03-25 20:53:15 +08:00
}