@ -1,170 +1,232 @@
# include "notelistmodel.h"
# include <QDebug>
# include "nodepath.h"
# include <QTimer>
# include <QMimeData>
# include <QDebug> // 包含调试输出头文件
# include "nodepath.h" // 包含节点路径头文件
# include <QTimer> // 包含定时器头文件
# include <QMimeData> // 包含MIME数据头文件
NoteListModel : : NoteListModel ( QObject * parent ) : QAbstractListModel ( parent ) { }
NoteListModel : : ~ NoteListModel ( ) { }
// 添加笔记
QModelIndex NoteListModel : : addNote ( const NodeData & note )
{
// 如果笔记不是被钉住的
if ( ! note . isPinnedNote ( ) ) {
// 获取当前行数
const int rowCnt = rowCount ( ) ;
// 开始插入行
beginInsertRows ( QModelIndex ( ) , rowCnt , rowCnt ) ;
// 将笔记添加到笔记列表
m_noteList < < note ;
// 结束插入行
endInsertRows ( ) ;
// 发出行插入信号
emit rowsInsertedC ( { createIndex ( rowCnt , 0 ) } ) ;
// 发出行数变化信号
emit rowCountChanged ( ) ;
// 返回新笔记的模型索引
return createIndex ( rowCnt , 0 ) ;
} else {
// 获取被钉住的笔记列表的大小
const int rowCnt = m_pinnedList . size ( ) ;
// 开始插入行
beginInsertRows ( QModelIndex ( ) , rowCnt , rowCnt ) ;
// 将笔记添加到被钉住的笔记列表
m_pinnedList < < note ;
// 结束插入行
endInsertRows ( ) ;
// 发出行插入信号
emit rowsInsertedC ( { createIndex ( rowCnt , 0 ) } ) ;
// 发出行数变化信号
emit rowCountChanged ( ) ;
// 返回新笔记的模型索引
return createIndex ( rowCnt , 0 ) ;
}
}
// 在指定行插入笔记
QModelIndex NoteListModel : : insertNote ( const NodeData & note , int row )
{
{ // 如果笔记是被钉住的
if ( note . isPinnedNote ( ) ) {
// 如果指定行大于被钉住的笔记列表的大小,则设置为列表的末尾
if ( row > m_pinnedList . size ( ) ) {
row = m_pinnedList . size ( ) ;
} else if ( row < 0 ) {
} else if ( row < 0 ) { // 如果指定行小于0, 则设置为列表的开头
row = 0 ;
}
// 开始在被钉住的笔记列表的指定行插入一行
beginInsertRows ( QModelIndex ( ) , row , row ) ;
// 将笔记插入到被钉住的笔记列表的指定行
m_pinnedList . insert ( row , note ) ;
// 结束插入行
endInsertRows ( ) ;
// 发出新笔记插入信号
emit rowsInsertedC ( { createIndex ( row , 0 ) } ) ;
// 发出行数变化信号
emit rowCountChanged ( ) ;
// 返回新笔记的模型索引
return createIndex ( row , 0 ) ;
} else {
// 如果指定行小于被钉住的笔记列表的大小,则设置为被钉住的笔记列表的末尾
if ( row < m_pinnedList . size ( ) ) {
row = m_pinnedList . size ( ) ;
} else if ( row > ( m_pinnedList . size ( ) + m_noteList . size ( ) ) ) {
// 如果指定行大于笔记列表的总大小,则设置为笔记列表的末尾
row = m_pinnedList . size ( ) + m_noteList . size ( ) ;
}
// 开始在笔记列表的指定行插入一行
beginInsertRows ( QModelIndex ( ) , row , row ) ;
// 将笔记插入到笔记列表的指定行
m_noteList . insert ( row - m_pinnedList . size ( ) , note ) ;
// 结束插入行
endInsertRows ( ) ;
// 发出新笔记插入信号
emit rowsInsertedC ( { createIndex ( row , 0 ) } ) ;
// 发出行数变化信号
emit rowCountChanged ( ) ;
// 返回新笔记的模型索引
return createIndex ( row , 0 ) ;
}
}
// 获取指定模型索引的笔记数据
const NodeData & NoteListModel : : getNote ( const QModelIndex & index ) const
{
// 获取模型索引的行号
auto row = index . row ( ) ;
// 如果行号小于被钉住的笔记列表的大小,则从被钉住的笔记列表中获取笔记数据
if ( row < m_pinnedList . size ( ) ) {
return m_pinnedList . at ( row ) ;
} else {
} else { // 否则从笔记列表中获取笔记数据
row = row - m_pinnedList . size ( ) ;
return m_noteList . at ( row ) ;
}
}
// 获取指定ID的笔记的模型索引
QModelIndex NoteListModel : : getNoteIndex ( int id ) const
{
{ // 在被钉住的笔记列表中查找ID匹配的笔记
for ( int i = 0 ; i < m_pinnedList . size ( ) ; + + i ) {
if ( m_pinnedList [ i ] . id ( ) = = id ) {
return createIndex ( i , 0 ) ;
}
}
// 在笔记列表中查找ID匹配的笔记
for ( int i = 0 ; i < m_noteList . size ( ) ; + + i ) {
if ( m_noteList [ i ] . id ( ) = = id ) {
return createIndex ( i + m_pinnedList . size ( ) , 0 ) ;
}
}
} // 如果未找到匹配的笔记,则返回无效的模型索引
return QModelIndex { } ;
}
// 设置笔记列表和列表视图信息
void NoteListModel : : setListNote ( const QVector < NodeData > & notes , const ListViewInfo & inf )
{
// 开始重置模型
beginResetModel ( ) ;
// 清空被钉住的笔记列表
m_pinnedList . clear ( ) ;
// 清空笔记列表
m_noteList . clear ( ) ;
// 设置列表视图信息
m_listViewInfo = inf ;
// 如果不在标签中且不在回收站文件夹中
if ( ( ! m_listViewInfo . isInTag )
& & ( m_listViewInfo . parentFolderId ! = SpecialNodeID : : TrashFolder ) ) {
// 遍历笔记列表
for ( const auto & note : qAsConst ( notes ) ) {
// 如果笔记是被钉住的,则添加到被钉住的笔记列表
if ( note . isPinnedNote ( ) ) {
m_pinnedList . append ( note ) ;
} else {
} else { // 否则添加到笔记列表
m_noteList . append ( note ) ;
}
}
} else {
} else { // 否则直接将笔记列表赋值给笔记列表
m_noteList = notes ;
}
// 按升序排序
sort ( 0 , Qt : : AscendingOrder ) ;
// 结束重置模型
endResetModel ( ) ;
// 发出行数变化信号
emit rowCountChanged ( ) ;
}
// 移除指定模型索引列表的笔记
void NoteListModel : : removeNotes ( const QModelIndexList & noteIndexes )
{
emit requestRemoveNotes ( noteIndexes ) ;
emit requestRemoveNotes ( noteIndexes ) ; // 发出请求移除笔记信号
}
// 移动行
bool NoteListModel : : moveRow ( const QModelIndex & sourceParent , int sourceRow ,
const QModelIndex & destinationParent , int destinationChild )
{
{ // 如果源行号或目标行号超出范围, 则返回false
if ( sourceRow < 0 | | sourceRow > = rowCount ( ) | | destinationChild < 0
| | destinationChild > = rowCount ( ) ) {
return false ;
}
} // 如果源行号和目标行号都在被钉住的笔记列表范围内
if ( sourceRow < m_pinnedList . size ( ) & & destinationChild < m_pinnedList . size ( ) ) {
if ( beginMoveRows ( sourceParent , sourceRow , sourceRow , destinationParent ,
destinationChild ) ) {
destinationChild ) ) { // 在被钉住的笔记列表中移动笔记
m_pinnedList . move ( sourceRow , destinationChild ) ;
// 结束移动行
endMoveRows ( ) ;
// 发出行即将被移动信号
emit rowsAboutToBeMovedC ( { createIndex ( sourceRow , 0 ) } ) ;
// 发出行移动后信号
emit rowsMovedC ( { createIndex ( destinationChild , 0 ) } ) ;
emit rowCountChanged ( ) ;
// 发出行数变化信号
return true ;
}
}
// 如果源行号和目标行号都在笔记列表范围内
if ( sourceRow > = m_pinnedList . size ( ) & & destinationChild > = m_pinnedList . size ( ) ) {
// 调整源行号和目标行号以适应笔记列表的范围
sourceRow = sourceRow - m_pinnedList . size ( ) ;
destinationChild = destinationChild - m_pinnedList . size ( ) ;
// 开始移动行
if ( beginMoveRows ( sourceParent , sourceRow , sourceRow , destinationParent ,
destinationChild ) ) {
// 在笔记列表中移动笔记
m_noteList . move ( sourceRow , destinationChild ) ;
endMoveRows ( ) ;
// 结束移动行
// 发出行即将被移动信号
emit rowsAboutToBeMovedC ( { createIndex ( sourceRow , 0 ) } ) ;
// 发出行移动后信号
emit rowsMovedC ( { createIndex ( destinationChild + 1 , 0 ) } ) ;
// 发出行数变化信号
emit rowCountChanged ( ) ;
return true ;
}
}
// 如果源行号和目标行号不在同一范围内, 则返回false
return false ;
}
// 清空笔记列表
void NoteListModel : : clearNotes ( )
{
// 开始重置模型
beginResetModel ( ) ;
// 清空被钉住的笔记列表
m_pinnedList . clear ( ) ;
// 清空笔记列表
m_noteList . clear ( ) ;
// 结束重置模型
endResetModel ( ) ;
// 发出行数变化信号
emit rowCountChanged ( ) ;
}
// 获取指定模型索引的数据的实现
QVariant NoteListModel : : data ( const QModelIndex & index , int role ) const
{
// 如果模型索引的行号超出范围, 则返回空的QVariant
if ( index . row ( ) < 0 | | index . row ( ) > = ( m_noteList . count ( ) + m_pinnedList . count ( ) ) ) {
return QVariant ( ) ;
}
// 如果角色超出范围, 则返回空的QVariant
if ( role < NoteID | | role > NoteIsPinned ) {
return QVariant ( ) ;
}
// 获取指定行的笔记数据
const NodeData & note = getRef ( index . row ( ) ) ;
// 根据角色返回相应的数据
if ( role = = NoteID ) {
return note . id ( ) ;
} else if ( role = = NoteFullTitle ) {
@ -198,14 +260,16 @@ QVariant NoteListModel::data(const QModelIndex &index, int role) const
return QVariant ( ) ;
}
// 设置指定模型索引的数据的实现
bool NoteListModel : : setData ( const QModelIndex & index , const QVariant & value , int role )
{
// 如果模型索引的行号超出范围, 则返回false
if ( index . row ( ) < 0 | | index . row ( ) > = ( m_noteList . count ( ) + m_pinnedList . count ( ) ) ) {
return false ;
}
// 获取指定行的笔记数据的引用
NodeData & note = getRef ( index . row ( ) ) ;
// 根据角色设置相应的数据
if ( role = = NoteID ) {
note . setId ( value . toInt ( ) ) ;
} else if ( role = = NoteFullTitle ) {
@ -231,37 +295,44 @@ bool NoteListModel::setData(const QModelIndex &index, const QVariant &value, int
} else {
return false ;
}
// 发出数据变化信号
emit dataChanged ( this - > index ( index . row ( ) ) , this - > index ( index . row ( ) ) , QVector < int > ( 1 , role ) ) ;
return true ;
}
// 获取指定模型索引的项标志
Qt : : ItemFlags NoteListModel : : flags ( const QModelIndex & index ) const
{
// 如果模型索引无效,则返回启用和可放置的项标志
if ( ! index . isValid ( ) ) {
return Qt : : ItemIsEnabled | Qt : : ItemIsDropEnabled ;
}
// 返回基类的项标志,并添加可编辑、可拖拽和可放置的项标志
return QAbstractListModel : : flags ( index ) | Qt : : ItemIsEditable | Qt : : ItemIsDragEnabled
| Qt : : ItemIsDropEnabled ;
}
// 获取行数
int NoteListModel : : rowCount ( const QModelIndex & parent ) const
{
// 忽略parent参数
Q_UNUSED ( parent )
// 返回笔记列表和被钉住的笔记列表的总大小
return m_noteList . size ( ) + m_pinnedList . size ( ) ;
}
// 排序
void NoteListModel : : sort ( int column , Qt : : SortOrder order )
{
// 忽略column和order参数
Q_UNUSED ( column )
Q_UNUSED ( order )
// 如果在回收站文件夹中
if ( m_listViewInfo . parentFolderId = = SpecialNodeID : : TrashFolder ) {
// 按删除日期时间降序排序笔记列表
std : : stable_sort ( m_noteList . begin ( ) , m_noteList . end ( ) ,
[ ] ( const NodeData & lhs , const NodeData & rhs ) {
return lhs . deletionDateTime ( ) > rhs . deletionDateTime ( ) ;
} ) ;
} else {
} else { // 否则按相对位置升序排序被钉住的笔记列表
std : : stable_sort ( m_pinnedList . begin ( ) , m_pinnedList . end ( ) ,
[ this ] ( const NodeData & lhs , const NodeData & rhs ) {
if ( isInAllNote ( ) ) {
@ -270,176 +341,217 @@ void NoteListModel::sort(int column, Qt::SortOrder order)
return lhs . relativePosition ( ) < rhs . relativePosition ( ) ;
}
} ) ;
// 按最后修改日期时间降序排序笔记列表
std : : stable_sort ( m_noteList . begin ( ) , m_noteList . end ( ) ,
[ ] ( const NodeData & lhs , const NodeData & rhs ) {
return lhs . lastModificationdateTime ( ) > rhs . lastModificationdateTime ( ) ;
} ) ;
}
// 发出数据变化信号
emit dataChanged ( index ( 0 ) , index ( rowCount ( ) - 1 ) ) ;
}
// 设置指定模型索引的笔记数据
void NoteListModel : : setNoteData ( const QModelIndex & index , const NodeData & note )
{
// 如果模型索引无效,则返回
if ( ! index . isValid ( ) ) {
return ;
}
auto row = index . row ( ) ;
auto row = index . row ( ) ; // 获取模型索引的行号
// 如果行号小于被钉住的笔记列表的大小,则在被钉住的笔记列表中设置笔记数据
if ( row < m_pinnedList . size ( ) ) {
m_pinnedList [ row ] = note ;
} else {
} else { // 否则在笔记列表中设置笔记数据
row = row - m_pinnedList . size ( ) ;
m_noteList [ row ] = note ;
}
// 发出数据变化信号
emit dataChanged ( this - > index ( index . row ( ) ) , this - > index ( index . row ( ) ) ) ;
}
// 更新被钉住的笔记的相对位置的实现
void NoteListModel : : updatePinnedRelativePosition ( )
{
// 遍历被钉住的笔记列表
for ( int i = 0 ; i < m_pinnedList . size ( ) ; + + i ) {
// 如果不在所有笔记中
if ( ! isInAllNote ( ) ) {
// 发出请求更新笔记的相对位置信号
emit requestUpdatePinnedRelPos ( m_pinnedList [ i ] . id ( ) , i ) ;
} else {
} else { // 否则发出请求更新笔记的相对位置(在所有笔记中)信号
emit requestUpdatePinnedRelPosAN ( m_pinnedList [ i ] . id ( ) , i ) ;
}
}
}
// 检查是否在所有笔记中
bool NoteListModel : : isInAllNote ( ) const
{
return ( ! m_listViewInfo . isInTag )
return ( ! m_listViewInfo . isInTag ) // 如果不在标签中且在根文件夹中, 则返回true
& & ( m_listViewInfo . parentFolderId = = SpecialNodeID : : RootFolder ) ;
}
// 获取指定行的笔记数据的引用
NodeData & NoteListModel : : getRef ( int row )
{
// 如果行号小于被钉住的笔记列表的大小,则从被钉住的笔记列表中获取笔记数据的引用
if ( row < m_pinnedList . size ( ) )
return m_pinnedList [ row ] ;
// 否则从笔记列表中获取笔记数据的引用
return m_noteList [ row - m_pinnedList . size ( ) ] ;
}
// 获取指定行的笔记数据的常量引用
const NodeData & NoteListModel : : getRef ( int row ) const
{
// 如果行号小于被钉住的笔记列表的大小,则从被钉住的笔记列表中获取笔记数据的常量引用
if ( row < m_pinnedList . size ( ) )
return m_pinnedList [ row ] ;
// 否则从笔记列表中获取笔记数据的常量引用
return m_noteList [ row - m_pinnedList . size ( ) ] ;
}
// 移除行
bool NoteListModel : : removeRows ( int row , int count , const QModelIndex & parent )
{
if ( row < 0 | | ( row + count ) > ( m_pinnedList . size ( ) + m_noteList . size ( ) ) ) {
if ( row < 0 | | ( row + count ) > ( m_pinnedList . size ( ) + m_noteList . size ( ) ) ) { // 如果行号或行数超出范围, 则返回false
return false ;
}
beginRemoveRows ( parent , row , row + count - 1 ) ;
for ( int r = row ; r < row + count ; + + r ) {
beginRemoveRows ( parent , row , row + count - 1 ) ; // 开始移除行
for ( int r = row ; r < row + count ; + + r ) { // 遍历要移除的行
// 如果行号小于被钉住的笔记列表的大小,则从被钉住的笔记列表中移除笔记
if ( r < m_pinnedList . size ( ) ) {
m_pinnedList . takeAt ( r ) ;
} else {
} else { // 否则从笔记列表中移除笔记
auto rr = r - m_pinnedList . size ( ) ;
m_noteList . takeAt ( rr ) ;
}
}
} // 结束移除行
endRemoveRows ( ) ;
emit rowCountChanged ( ) ;
emit rowCountChanged ( ) ; // 发出行数变化信号
return true ;
}
// 获取支持的拖放操作
Qt : : DropActions NoteListModel : : supportedDropActions ( ) const
{
return Qt : : MoveAction ;
return Qt : : MoveAction ; // 返回移动操作
}
// 获取支持的拖拽操作
Qt : : DropActions NoteListModel : : supportedDragActions ( ) const
{
return Qt : : MoveAction ;
return Qt : : MoveAction ; // 返回移动操作
}
// 获取支持的MIME类型
QStringList NoteListModel : : mimeTypes ( ) const
{
return QStringList ( ) < < NOTE_MIME ;
return QStringList ( ) < < NOTE_MIME ; // 返回包含笔记MIME类型的列表
}
// 获取指定模型索引列表的MIME数据
QMimeData * NoteListModel : : mimeData ( const QModelIndexList & indexes ) const
{
// 如果模型索引列表为空, 则返回nullptr
if ( indexes . isEmpty ( ) ) {
return nullptr ;
}
QStringList d ;
for ( const auto & index : indexes ) {
QStringList d ; // 创建一个字符串列表来存储笔记ID
for ( const auto & index : indexes ) { // 遍历模型索引列表
// 获取笔记ID并添加到字符串列表中
auto id = index . data ( NoteListModel : : NoteID ) . toInt ( ) ;
d . append ( QString : : number ( id ) ) ;
}
if ( d . isEmpty ( ) ) {
return nullptr ;
return nullptr ; // 如果字符串列表为空, 则返回nullptr
}
QMimeData * mimeData = new QMimeData ;
mimeData - > setData ( NOTE_MIME , d . join ( QStringLiteral ( PATH_SEPARATOR ) ) . toUtf8 ( ) ) ;
QMimeData * mimeData = new QMimeData ; // 创建一个新的QMimeData对象
mimeData - > setData ( NOTE_MIME , d . join ( QStringLiteral ( PATH_SEPARATOR ) ) . toUtf8 ( ) ) ; // 将笔记ID列表设置为MIME数据
return mimeData ;
}
// 处理MIME数据的拖放
bool NoteListModel : : dropMimeData ( const QMimeData * mime , Qt : : DropAction action , int row , int column ,
const QModelIndex & parent )
{
{ // 忽略column参数
Q_UNUSED ( column ) ;
// 如果MIME数据不包含笔记MIME类型或操作不是移动操作, 则返回false
if ( ! ( mime - > hasFormat ( NOTE_MIME ) & & action = = Qt : : MoveAction ) ) {
return false ;
}
// 如果行号为-1, 则根据parent的有效性确定行号
if ( row = = - 1 ) {
// valid index: drop onto item
// 如果parent有效, 则行号为parent的行号
if ( parent . isValid ( ) ) {
row = parent . row ( ) ;
} else {
} else { // 否则行号为模型的行数
// invalid index: append at bottom, after last toplevel
row = rowCount ( parent ) ;
}
}
// 根据行号确定是否移动到被钉住的笔记列表
bool toPinned = false ;
if ( row > = m_pinnedList . size ( ) ) {
toPinned = false ;
} else {
toPinned = true ;
}
} // 获取笔记ID列表
auto idl = QString : : fromUtf8 ( mime - > data ( NOTE_MIME ) ) . split ( QStringLiteral ( PATH_SEPARATOR ) ) ;
// 创建一个QSet来存储移动的笔记ID
QSet < int > movedIds ;
// 创建一个QModelIndexList来存储移动的笔记的模型索引
QModelIndexList idxe ;
// 遍历笔记ID列表
for ( const auto & id_s : qAsConst ( idl ) ) {
// 获取笔记ID并添加到模型索引列表中
auto nodeId = id_s . toInt ( ) ;
idxe . append ( getNoteIndex ( nodeId ) ) ;
}
// 发出行即将被移动信号
emit rowsAboutToBeMovedC ( idxe ) ;
// 开始重置模型
beginResetModel ( ) ;
// 如果移动到被钉住的笔记列表
if ( toPinned ) {
// 遍历移动的笔记的模型索引列表
for ( const auto & index : qAsConst ( idxe ) ) {
// 获取笔记数据的引用
auto & note = getRef ( index . row ( ) ) ;
// 如果笔记不是被钉住的,则设置为被钉住的
if ( ! note . isPinnedNote ( ) ) {
note . setIsPinnedNote ( true ) ;
// 发出请求更新笔记的钉住状态信号
emit requestUpdatePinned ( note . id ( ) , true ) ;
// 将笔记从笔记列表移动到被钉住的笔记列表的开头
m_pinnedList . prepend ( m_noteList . takeAt ( index . row ( ) - m_pinnedList . size ( ) ) ) ;
}
}
// 遍历笔记ID列表
for ( const auto & id_s : qAsConst ( idl ) ) {
// 获取笔记ID
auto nodeId = id_s . toInt ( ) ;
// 遍历被钉住的笔记列表
for ( int i = 0 ; i < m_pinnedList . size ( ) ; + + i ) {
// 如果找到匹配的笔记,则移动到指定行
if ( m_pinnedList [ i ] . id ( ) = = nodeId ) {
m_pinnedList . move ( i , row ) ;
break ;
}
}
movedIds . insert ( nodeId ) ;
movedIds . insert ( nodeId ) ; // 将笔记ID添加到移动的笔记ID集合中
}
} else {
} else { // 否则移动到笔记列表
// 遍历移动的笔记的模型索引列表
for ( const auto & index : qAsConst ( idxe ) ) {
// 获取笔记数据的引用
auto & note = getRef ( index . row ( ) ) ;
// 将笔记ID添加到移动的笔记ID集合中
movedIds . insert ( note . id ( ) ) ;
// 如果笔记是被钉住的,则设置为不是被钉住的
if ( ! note . isPinnedNote ( ) ) {
continue ;
}
note . setIsPinnedNote ( false ) ;
// 发出请求更新笔记的钉住状态信号
emit requestUpdatePinned ( note . id ( ) , false ) ;
// 根据当前视图确定插入位置
int destinationChild = 0 ;
if ( m_listViewInfo . parentFolderId = = SpecialNodeID : : TrashFolder ) {
// 如果在回收站文件夹中,则按删除日期时间排序
auto lastMod = index . data ( NoteDeletionDateTime ) . toDateTime ( ) ;
for ( destinationChild = 0 ; destinationChild < m_noteList . size ( ) ;
+ + destinationChild ) {
@ -447,7 +559,7 @@ bool NoteListModel::dropMimeData(const QMimeData *mime, Qt::DropAction action, i
break ;
}
}
} else {
} else { // 否则按最后修改日期时间排序
auto lastMod = index . data ( NoteLastModificationDateTime ) . toDateTime ( ) ;
for ( destinationChild = 0 ; destinationChild < m_noteList . size ( ) ;
+ + destinationChild ) {
@ -455,99 +567,141 @@ bool NoteListModel::dropMimeData(const QMimeData *mime, Qt::DropAction action, i
break ;
}
}
}
} // 将笔记从被钉住的笔记列表移动到笔记列表的指定位置
m_noteList . insert ( destinationChild , m_pinnedList . takeAt ( index . row ( ) ) ) ;
}
}
// 结束重置模型
endResetModel ( ) ;
// 创建一个QModelIndexList来存储移动后的笔记的模型索引
QModelIndexList destinations ;
// 遍历移动的笔记ID集合
for ( const auto & id : movedIds ) {
// 获取笔记的模型索引并添加到模型索引列表中
auto index = getNoteIndex ( id ) ;
if ( ! index . isValid ( ) ) {
continue ;
}
destinations . append ( index ) ;
}
// 发出选择笔记信号
emit selectNotes ( destinations ) ;
// 发出行移动后信号
emit rowsMovedC ( destinations ) ;
// 更新被钉住的笔记的相对位置
updatePinnedRelativePosition ( ) ;
return true ;
}
// 获取第一个未被钉住的笔记的模型索引
QModelIndex NoteListModel : : getFirstUnpinnedNote ( ) const
{
{ // 如果笔记列表不为空,则返回第一个未被钉住的笔记的模型索引
if ( ! m_noteList . isEmpty ( ) ) {
return createIndex ( m_pinnedList . size ( ) , 0 ) ;
} else {
} else { // 否则返回无效的模型索引
return QModelIndex ( ) ;
}
}
// 检查是否有被钉住的笔记
bool NoteListModel : : hasPinnedNote ( ) const
{
// 如果不在标签中且不在回收站文件夹中
if ( ( ! m_listViewInfo . isInTag )
& & ( m_listViewInfo . parentFolderId = = SpecialNodeID : : TrashFolder ) ) {
// 回收站文件夹中没有被钉住的笔记, 返回false
// Trash don't have pinned note
return false ;
}
} // 如果被钉住的笔记列表不为空, 则返回true
return ! m_pinnedList . isEmpty ( ) ;
}
// 设置指定模型索引列表的笔记的钉住状态的实现
void NoteListModel : : setNotesIsPinned ( const QModelIndexList & indexes , bool isPinned )
{
// 发出请求关闭笔记编辑器信号
emit requestCloseNoteEditor ( indexes ) ;
// 创建一个QSet来存储需要移动的笔记ID
QSet < int > needMovingIds ;
// 创建一个QModelIndexList来存储需要移动的笔记的模型索引
QModelIndexList needMovingIndexes ;
// 遍历模型索引列表
for ( const auto & index : indexes ) {
// 如果模型索引有效
if ( index . isValid ( ) ) {
// 获取笔记数据的引用
NodeData & note = getRef ( index . row ( ) ) ;
// 如果笔记的钉住状态需要改变
if ( note . isPinnedNote ( ) ! = isPinned ) {
// 将笔记ID添加到需要移动的笔记ID集合中
needMovingIds . insert ( note . id ( ) ) ;
// 将模型索引添加到需要移动的笔记的模型索引列表中
needMovingIndexes . append ( index ) ;
// 设置笔记的钉住状态
note . setIsPinnedNote ( isPinned ) ;
// 发出请求更新笔记的钉住状态信号
emit requestUpdatePinned ( note . id ( ) , isPinned ) ;
}
}
}
// 如果设置为被钉住的
if ( isPinned ) {
// 发出行即将被移动信号
emit rowsAboutToBeMovedC ( needMovingIndexes ) ;
// 开始重置模型
beginResetModel ( ) ;
// 遍历需要移动的笔记ID集合
for ( const auto & id : qAsConst ( needMovingIds ) ) {
// 获取笔记的模型索引
auto index = getNoteIndex ( id ) ;
if ( ! index . isValid ( ) ) {
continue ;
}
// 获取源行号
int sourceRow = index . row ( ) ;
// 如果源行号超出范围,则继续下一个
if ( sourceRow < 0 | | sourceRow > = rowCount ( ) ) {
continue ;
}
// 将笔记从笔记列表移动到被钉住的笔记列表的开头
m_pinnedList . prepend ( m_noteList . takeAt ( sourceRow - m_pinnedList . size ( ) ) ) ;
}
// 结束重置模型
endResetModel ( ) ;
// 创建一个QModelIndexList来存储移动后的笔记的模型索引
QModelIndexList destinations ;
for ( const auto & id : needMovingIds ) {
// 遍历需要移动的笔记ID集合
for ( const auto & id : qAsConst ( needMovingIds ) ) {
// 获取笔记的模型索引并添加到模型索引列表中
auto index = getNoteIndex ( id ) ;
if ( ! index . isValid ( ) ) {
continue ;
}
destinations . append ( index ) ;
}
// 发出选择笔记信号
emit selectNotes ( destinations ) ;
// 发出行移动后信号
emit rowsMovedC ( destinations ) ;
// 发出行数变化信号
emit rowCountChanged ( ) ;
// 更新被钉住的笔记的相对位置
updatePinnedRelativePosition ( ) ;
} else {
} else { // 否则设置为不是被钉住的
// 发出行即将被移动信号
emit rowsAboutToBeMovedC ( needMovingIndexes ) ;
// 开始重置模型
beginResetModel ( ) ;
// 遍历需要移动的笔记ID集合
for ( const auto & id : qAsConst ( needMovingIds ) ) {
// 获取笔记的模型索引
auto index = getNoteIndex ( id ) ;
if ( ! index . isValid ( ) ) {
continue ;
}
int destinationChild = 0 ;
if ( m_listViewInfo . parentFolderId = = SpecialNodeID : : TrashFolder ) {
// 如果在回收站文件夹中,则按删除日期时间排序
auto lastMod = index . data ( NoteDeletionDateTime ) . toDateTime ( ) ;
for ( destinationChild = 0 ; destinationChild < m_noteList . size ( ) ;
+ + destinationChild ) {
@ -556,7 +710,7 @@ void NoteListModel::setNotesIsPinned(const QModelIndexList &indexes, bool isPinn
break ;
}
}
} else {
} else { // 否则按最后修改日期时间排序
auto lastMod = index . data ( NoteLastModificationDateTime ) . toDateTime ( ) ;
for ( destinationChild = 0 ; destinationChild < m_noteList . size ( ) ;
+ + destinationChild ) {
@ -565,72 +719,89 @@ void NoteListModel::setNotesIsPinned(const QModelIndexList &indexes, bool isPinn
break ;
}
}
}
} // 将笔记从被钉住的笔记列表移动到笔记列表的指定位置
m_noteList . insert ( destinationChild , m_pinnedList . takeAt ( index . row ( ) ) ) ;
}
// 结束重置模型
endResetModel ( ) ;
// 创建一个QModelIndexList来存储移动后的笔记的模型索引
QModelIndexList destinations ;
// 遍历需要移动的笔记ID集合
for ( const auto & id : needMovingIds ) {
// 获取笔记的模型索引并添加到模型索引列表中
auto index = getNoteIndex ( id ) ;
if ( ! index . isValid ( ) ) {
continue ;
}
destinations . append ( index ) ;
}
// 发出选择笔记信号
emit selectNotes ( destinations ) ;
// 发出行移动后信号
emit rowsMovedC ( destinations ) ;
// 发出行数变化信号
emit rowCountChanged ( ) ;
// 更新被钉住的笔记的相对位置
updatePinnedRelativePosition ( ) ;
}
}
// 检查指定模型索引的笔记是否具有标签
bool NoteListModel : : noteIsHaveTag ( const QModelIndex & index ) const
{
{ // 如果模型索引无效, 则返回false
if ( index . row ( ) < 0 | | index . row ( ) > = ( m_noteList . count ( ) + m_pinnedList . count ( ) ) ) {
return false ;
}
// 获取模型索引的行号
auto row = index . row ( ) ;
// 创建一个NodeData对象来存储笔记数据
NodeData note ;
// 如果行号小于被钉住的笔记列表的大小,则从被钉住的笔记列表中获取笔记数据
if ( row < m_pinnedList . size ( ) ) {
note = m_pinnedList [ row ] ;
} else {
} else { // 否则从笔记列表中获取笔记数据
row = row - m_pinnedList . size ( ) ;
note = m_noteList [ row ] ;
}
return ! note . tagIds ( ) . empty ( ) ;
return ! note . tagIds ( ) . empty ( ) ; // 如果笔记的标签列表不为空, 则返回true
}
// 检查指定模型索引的笔记是否为第一个被钉住的笔记
bool NoteListModel : : isFirstPinnedNote ( const QModelIndex & index ) const
{
// 如果模型索引无效, 则返回false
if ( ! index . isValid ( ) ) {
return false ;
}
// 如果模型索引的行号大于0, 则返回false
if ( index . row ( ) > 0 ) {
return false ;
}
// 获取指定行的笔记数据的常量引用
const NodeData & note = getRef ( index . row ( ) ) ;
// 如果模型索引的行号为0且笔记是被钉住的, 则返回true
if ( index . row ( ) = = 0 & & note . isPinnedNote ( ) ) {
return true ;
}
return false ;
}
// 检查指定模型索引的笔记是否为第一个未被钉住的笔记
bool NoteListModel : : isFirstUnpinnedNote ( const QModelIndex & index ) const
{
{ // 如果模型索引无效, 则返回false
if ( ! index . isValid ( ) ) {
return false ;
}
// 获取指定行的笔记数据的常量引用
const NodeData & note = getRef ( index . row ( ) ) ;
if ( ( index . row ( ) - m_pinnedList . size ( ) ) = = 0 & & ! note . isPinnedNote ( ) ) {
if ( ( index . row ( ) - m_pinnedList . size ( ) ) = = 0 & & ! note . isPinnedNote ( ) ) { // 如果模型索引的行号减去被钉住的笔记列表的大小为0且笔记不是被钉住的, 则返回true
return true ;
}
return false ;
}
// 获取第一个被钉住的笔记的模型索引
QModelIndex NoteListModel : : getFirstPinnedNote ( ) const
{
if ( m_pinnedList . isEmpty ( ) ) {
if ( m_pinnedList . isEmpty ( ) ) { // 如果被钉住的笔记列表不为空,则返回第一个被钉住的笔记的模型索引
return QModelIndex ( ) ;
}
} // 否则返回无效的模型索引
return createIndex ( 0 , 0 ) ;
}