feat: Pagination/virtualization (fetchMore) for EmailListModel

- EmailListModel: QAbstractListModel with canFetchMore/fetchMore
  * Batch loading (default 50 emails per fetch)
  * Total count query for scrollbar
  * TotalCountChanged signal
  * Paginated DB queries: findAllPaginated, findByFolderIdPaginated
  * Count queries: countAll, countByFolderId

- MailItemDao: new paginated methods
  * findAllPaginated(offset, limit, filters...)
  * findByFolderIdPaginated(folderId, offset, limit, filters...)
  * countAll(filters...), countByFolderId(folderId, filters...)

- MailListView: scroll-triggered fetchMore
  * Connects verticalScrollBar valueChanged on both TreeView and ListView
  * Triggers fetchMore at 90% scroll threshold
  * onRowsInserted updates EmailTreeModel when new emails arrive
  * Works in both normal (tree) and compact (list) views
This commit is contained in:
2026-08-25 22:20:06 +02:00
parent 6e6fdf9c21
commit 68d237c873
77 changed files with 16718 additions and 18159 deletions
@@ -69,7 +69,16 @@ template <> constexpr inline auto MailListView::qt_create_metaobjectdata<qt_meta
"onCompactReplyRequested",
"onCompactForwardRequested",
"onCompactMarkUnreadRequested",
"onDisplayModeChanged"
"onDisplayModeChanged",
"onTotalCountChanged",
"count",
"onTreeViewScrolled",
"value",
"onListViewScrolled",
"onRowsInserted",
"parent",
"first",
"last"
};
QtMocHelpers::UintData qt_methods {
@@ -161,6 +170,22 @@ template <> constexpr inline auto MailListView::qt_create_metaobjectdata<qt_meta
QtMocHelpers::SlotData<void(int)>(30, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 17 },
}}),
// Slot 'onTotalCountChanged'
QtMocHelpers::SlotData<void(int)>(31, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 32 },
}}),
// Slot 'onTreeViewScrolled'
QtMocHelpers::SlotData<void(int)>(33, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 34 },
}}),
// Slot 'onListViewScrolled'
QtMocHelpers::SlotData<void(int)>(35, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 34 },
}}),
// Slot 'onRowsInserted'
QtMocHelpers::SlotData<void(const QModelIndex &, int, int)>(36, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ 0x80000000 | 16, 37 }, { QMetaType::Int, 38 }, { QMetaType::Int, 39 },
}}),
};
QtMocHelpers::UintData qt_properties {
};
@@ -207,6 +232,10 @@ void MailListView::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id
case 20: _t->onCompactForwardRequested((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 21: _t->onCompactMarkUnreadRequested((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 22: _t->onDisplayModeChanged((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 23: _t->onTotalCountChanged((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 24: _t->onTreeViewScrolled((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 25: _t->onListViewScrolled((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 26: _t->onRowsInserted((*reinterpret_cast<std::add_pointer_t<QModelIndex>>(_a[1])),(*reinterpret_cast<std::add_pointer_t<int>>(_a[2])),(*reinterpret_cast<std::add_pointer_t<int>>(_a[3]))); break;
default: ;
}
}
@@ -253,14 +282,14 @@ int MailListView::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 23)
if (_id < 27)
qt_static_metacall(this, _c, _id, _a);
_id -= 23;
_id -= 27;
}
if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 23)
if (_id < 27)
*reinterpret_cast<QMetaType *>(_a[0]) = QMetaType();
_id -= 23;
_id -= 27;
}
return _id;
}