feat: Focused/Other pivot for Inbox

- MailListView: new m_pivotCombo (Principal/Otros) visible only for Inbox folders
- MailListView::setFolderType(folderType) called from MainMainWindow::onFolderSelected()
- Folder::type() returns 'inbox', 'sent', 'drafts', 'trash', 'custom'
- onPivotChanged() placeholder for future AI-based filtering (Focused vs Other)
- UI hidden for non-Inbox folders
This commit is contained in:
2026-08-26 03:33:10 +02:00
parent 43b828fe87
commit 3a3a7b0ff8
10 changed files with 8421 additions and 8355 deletions
File diff suppressed because it is too large Load Diff
Binary file not shown.
@@ -65,6 +65,8 @@ template <> constexpr inline auto MailListView::qt_create_metaobjectdata<qt_meta
"batchMarkUnreadRequested",
"batchMoveRequested",
"targetFolderId",
"setFolderType",
"folderType",
"onRowSelected",
"QModelIndex",
"index",
@@ -98,7 +100,8 @@ template <> constexpr inline auto MailListView::qt_create_metaobjectdata<qt_meta
"onBatchMoveClicked",
"onBatchDeleteClicked",
"enterMultiSelectMode",
"exitMultiSelectMode"
"exitMultiSelectMode",
"onPivotChanged"
};
QtMocHelpers::UintData qt_methods {
@@ -160,90 +163,98 @@ template <> constexpr inline auto MailListView::qt_create_metaobjectdata<qt_meta
QtMocHelpers::SignalData<void(const QVector<int> &, int)>(23, 2, QMC::AccessPublic, QMetaType::Void, {{
{ 0x80000000 | 16, 19 }, { QMetaType::Int, 24 },
}}),
// Slot 'setFolderType'
QtMocHelpers::SlotData<void(const QString &)>(25, 2, QMC::AccessPublic, QMetaType::Void, {{
{ QMetaType::QString, 26 },
}}),
// Slot 'onRowSelected'
QtMocHelpers::SlotData<void(const QModelIndex &)>(25, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ 0x80000000 | 26, 27 },
QtMocHelpers::SlotData<void(const QModelIndex &)>(27, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ 0x80000000 | 28, 29 },
}}),
// Slot 'onSearchTextChanged'
QtMocHelpers::SlotData<void(const QString &)>(28, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::QString, 29 },
QtMocHelpers::SlotData<void(const QString &)>(30, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::QString, 31 },
}}),
// Slot 'onFilterChanged'
QtMocHelpers::SlotData<void()>(30, 2, QMC::AccessPrivate, QMetaType::Void),
QtMocHelpers::SlotData<void()>(32, 2, QMC::AccessPrivate, QMetaType::Void),
// Slot 'onGroupByChanged'
QtMocHelpers::SlotData<void(int)>(31, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 27 },
QtMocHelpers::SlotData<void(int)>(33, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 29 },
}}),
// Slot 'onCompactFlagRequested'
QtMocHelpers::SlotData<void(int)>(32, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 3 },
}}),
// Slot 'onCompactDeleteRequested'
QtMocHelpers::SlotData<void(int)>(33, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 3 },
}}),
// Slot 'onCompactCategoryRequested'
QtMocHelpers::SlotData<void(int)>(34, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 3 },
}}),
// Slot 'onCompactMoreRequested'
QtMocHelpers::SlotData<void(int, const QPoint &)>(35, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 3 }, { 0x80000000 | 10, 11 },
// Slot 'onCompactDeleteRequested'
QtMocHelpers::SlotData<void(int)>(35, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 3 },
}}),
// Slot 'onCompactMailClicked'
// Slot 'onCompactCategoryRequested'
QtMocHelpers::SlotData<void(int)>(36, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 3 },
}}),
// Slot 'onCompactReplyRequested'
QtMocHelpers::SlotData<void(int)>(37, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 3 },
// Slot 'onCompactMoreRequested'
QtMocHelpers::SlotData<void(int, const QPoint &)>(37, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 3 }, { 0x80000000 | 10, 11 },
}}),
// Slot 'onCompactForwardRequested'
// Slot 'onCompactMailClicked'
QtMocHelpers::SlotData<void(int)>(38, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 3 },
}}),
// Slot 'onCompactMarkUnreadRequested'
// Slot 'onCompactReplyRequested'
QtMocHelpers::SlotData<void(int)>(39, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 3 },
}}),
// Slot 'onDisplayModeChanged'
// Slot 'onCompactForwardRequested'
QtMocHelpers::SlotData<void(int)>(40, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 27 },
{ QMetaType::Int, 3 },
}}),
// Slot 'onCompactMarkUnreadRequested'
QtMocHelpers::SlotData<void(int)>(41, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 3 },
}}),
// Slot 'onDisplayModeChanged'
QtMocHelpers::SlotData<void(int)>(42, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 29 },
}}),
// Slot 'onTotalCountChanged'
QtMocHelpers::SlotData<void(int)>(41, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 42 },
}}),
// Slot 'onTreeViewScrolled'
QtMocHelpers::SlotData<void(int)>(43, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 44 },
}}),
// Slot 'onListViewScrolled'
// Slot 'onTreeViewScrolled'
QtMocHelpers::SlotData<void(int)>(45, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 44 },
{ QMetaType::Int, 46 },
}}),
// Slot 'onListViewScrolled'
QtMocHelpers::SlotData<void(int)>(47, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 46 },
}}),
// Slot 'onRowsInserted'
QtMocHelpers::SlotData<void(const QModelIndex &, int, int)>(46, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ 0x80000000 | 26, 47 }, { QMetaType::Int, 48 }, { QMetaType::Int, 49 },
QtMocHelpers::SlotData<void(const QModelIndex &, int, int)>(48, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ 0x80000000 | 28, 49 }, { QMetaType::Int, 50 }, { QMetaType::Int, 51 },
}}),
// Slot 'onSelectionChanged'
QtMocHelpers::SlotData<void()>(50, 2, QMC::AccessPrivate, QMetaType::Void),
QtMocHelpers::SlotData<void()>(52, 2, QMC::AccessPrivate, QMetaType::Void),
// Slot 'onSelectAllToggled'
QtMocHelpers::SlotData<void(bool)>(51, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Bool, 52 },
QtMocHelpers::SlotData<void(bool)>(53, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Bool, 54 },
}}),
// Slot 'onBatchFlagClicked'
QtMocHelpers::SlotData<void()>(53, 2, QMC::AccessPrivate, QMetaType::Void),
// Slot 'onBatchMarkUnreadClicked'
QtMocHelpers::SlotData<void()>(54, 2, QMC::AccessPrivate, QMetaType::Void),
// Slot 'onBatchMoveClicked'
QtMocHelpers::SlotData<void()>(55, 2, QMC::AccessPrivate, QMetaType::Void),
// Slot 'onBatchDeleteClicked'
// Slot 'onBatchMarkUnreadClicked'
QtMocHelpers::SlotData<void()>(56, 2, QMC::AccessPrivate, QMetaType::Void),
// Slot 'enterMultiSelectMode'
// Slot 'onBatchMoveClicked'
QtMocHelpers::SlotData<void()>(57, 2, QMC::AccessPrivate, QMetaType::Void),
// Slot 'exitMultiSelectMode'
// Slot 'onBatchDeleteClicked'
QtMocHelpers::SlotData<void()>(58, 2, QMC::AccessPrivate, QMetaType::Void),
// Slot 'enterMultiSelectMode'
QtMocHelpers::SlotData<void()>(59, 2, QMC::AccessPrivate, QMetaType::Void),
// Slot 'exitMultiSelectMode'
QtMocHelpers::SlotData<void()>(60, 2, QMC::AccessPrivate, QMetaType::Void),
// Slot 'onPivotChanged'
QtMocHelpers::SlotData<void(int)>(61, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 29 },
}}),
};
QtMocHelpers::UintData qt_properties {
};
@@ -282,31 +293,33 @@ void MailListView::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id
case 12: _t->batchDeleteRequested((*reinterpret_cast<std::add_pointer_t<QList<int>>>(_a[1]))); break;
case 13: _t->batchMarkUnreadRequested((*reinterpret_cast<std::add_pointer_t<QList<int>>>(_a[1]))); break;
case 14: _t->batchMoveRequested((*reinterpret_cast<std::add_pointer_t<QList<int>>>(_a[1])),(*reinterpret_cast<std::add_pointer_t<int>>(_a[2]))); break;
case 15: _t->onRowSelected((*reinterpret_cast<std::add_pointer_t<QModelIndex>>(_a[1]))); break;
case 16: _t->onSearchTextChanged((*reinterpret_cast<std::add_pointer_t<QString>>(_a[1]))); break;
case 17: _t->onFilterChanged(); break;
case 18: _t->onGroupByChanged((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 19: _t->onCompactFlagRequested((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 20: _t->onCompactDeleteRequested((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 21: _t->onCompactCategoryRequested((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 22: _t->onCompactMoreRequested((*reinterpret_cast<std::add_pointer_t<int>>(_a[1])),(*reinterpret_cast<std::add_pointer_t<QPoint>>(_a[2]))); break;
case 23: _t->onCompactMailClicked((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 24: _t->onCompactReplyRequested((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 25: _t->onCompactForwardRequested((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 26: _t->onCompactMarkUnreadRequested((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 27: _t->onDisplayModeChanged((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 28: _t->onTotalCountChanged((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 29: _t->onTreeViewScrolled((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 30: _t->onListViewScrolled((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 31: _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;
case 32: _t->onSelectionChanged(); break;
case 33: _t->onSelectAllToggled((*reinterpret_cast<std::add_pointer_t<bool>>(_a[1]))); break;
case 34: _t->onBatchFlagClicked(); break;
case 35: _t->onBatchMarkUnreadClicked(); break;
case 36: _t->onBatchMoveClicked(); break;
case 37: _t->onBatchDeleteClicked(); break;
case 38: _t->enterMultiSelectMode(); break;
case 39: _t->exitMultiSelectMode(); break;
case 15: _t->setFolderType((*reinterpret_cast<std::add_pointer_t<QString>>(_a[1]))); break;
case 16: _t->onRowSelected((*reinterpret_cast<std::add_pointer_t<QModelIndex>>(_a[1]))); break;
case 17: _t->onSearchTextChanged((*reinterpret_cast<std::add_pointer_t<QString>>(_a[1]))); break;
case 18: _t->onFilterChanged(); break;
case 19: _t->onGroupByChanged((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 20: _t->onCompactFlagRequested((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 21: _t->onCompactDeleteRequested((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 22: _t->onCompactCategoryRequested((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 23: _t->onCompactMoreRequested((*reinterpret_cast<std::add_pointer_t<int>>(_a[1])),(*reinterpret_cast<std::add_pointer_t<QPoint>>(_a[2]))); break;
case 24: _t->onCompactMailClicked((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 25: _t->onCompactReplyRequested((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 26: _t->onCompactForwardRequested((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 27: _t->onCompactMarkUnreadRequested((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 28: _t->onDisplayModeChanged((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 29: _t->onTotalCountChanged((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 30: _t->onTreeViewScrolled((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 31: _t->onListViewScrolled((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 32: _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;
case 33: _t->onSelectionChanged(); break;
case 34: _t->onSelectAllToggled((*reinterpret_cast<std::add_pointer_t<bool>>(_a[1]))); break;
case 35: _t->onBatchFlagClicked(); break;
case 36: _t->onBatchMarkUnreadClicked(); break;
case 37: _t->onBatchMoveClicked(); break;
case 38: _t->onBatchDeleteClicked(); break;
case 39: _t->enterMultiSelectMode(); break;
case 40: _t->exitMultiSelectMode(); break;
case 41: _t->onPivotChanged((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
default: ;
}
}
@@ -403,14 +416,14 @@ int MailListView::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 40)
if (_id < 42)
qt_static_metacall(this, _c, _id, _a);
_id -= 40;
_id -= 42;
}
if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 40)
if (_id < 42)
qt_static_metacall(this, _c, _id, _a);
_id -= 40;
_id -= 42;
}
return _id;
}
+8
View File
@@ -38,6 +38,14 @@ public:
int unreadCount() const { return m_unreadCount; }
void setUnreadCount(int count) { m_unreadCount = count; }
QString type() const {
if (m_isInbox) return "inbox";
if (m_isSent) return "sent";
if (m_isDrafts) return "drafts";
if (m_isTrash) return "trash";
return "custom";
}
QDateTime lastSynced() const { return m_lastSynced; }
void setLastSynced(const QDateTime& lastSynced) { m_lastSynced = lastSynced; }
+38
View File
@@ -77,6 +77,22 @@ void MailListView::setupUI()
filterLayout->addStretch();
// Pivot control (Focused/Other) - only shown for Inbox folders
m_pivotCombo = new QComboBox();
m_pivotCombo->addItem("Principal"); // Focused
m_pivotCombo->addItem("Otros"); // Other
m_pivotCombo->setFixedWidth(140);
m_pivotCombo->setStyleSheet(
"QComboBox { border: 1px solid #d1d1d6; border-radius: 4px; padding: 4px 8px; "
"background: white; min-height: 20px; }"
"QComboBox:hover { border-color: #bdbdbd; }"
"QComboBox:focus { border-color: #1976D2; }"
);
m_pivotCombo->setVisible(false); // Only visible for Inbox
connect(m_pivotCombo, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &MailListView::onPivotChanged);
filterLayout->addWidget(m_pivotCombo);
// Display mode combo (Compact/Medium/Spacious)
m_displayModeCombo = new QComboBox();
m_displayModeCombo->addItem("Compacto");
@@ -582,3 +598,25 @@ void MailListView::onBatchDeleteClicked()
emit batchDeleteRequested(m_selectedMailIds);
exitMultiSelectMode();
}
void MailListView::setFolderType(const QString& folderType)
{
m_pivotCombo->setVisible(folderType == "inbox");
}
void MailListView::onPivotChanged(int index)
{
// 0 = Focused (Principal), 1 = Other (Otros)
// TODO: Implement pivot filtering logic
// For now, just update the model filter
if (!m_sourceModel) return;
if (index == 0) {
// Focused: important emails (could be based on sender frequency, AI, etc.)
// m_sourceModel->setShowFocusedOnly(true);
} else {
// Other: promotional, notifications, etc.
// m_sourceModel->setShowFocusedOnly(false);
}
refreshViews();
}
+5
View File
@@ -48,6 +48,9 @@ signals:
void batchMarkUnreadRequested(const QVector<int>& mailIds);
void batchMoveRequested(const QVector<int>& mailIds, int targetFolderId);
public slots:
void setFolderType(const QString& folderType); // "inbox", "sent", "drafts", etc.
private slots:
void onRowSelected(const QModelIndex &index);
void onSearchTextChanged(const QString &text);
@@ -74,6 +77,7 @@ private slots:
void onBatchDeleteClicked();
void enterMultiSelectMode();
void exitMultiSelectMode();
void onPivotChanged(int index); // Focused/Other pivot
protected:
void resizeEvent(QResizeEvent *event) override;
@@ -101,6 +105,7 @@ private:
QWidget *m_actionBar; // Action bar widget
QComboBox *m_groupByCombo;
QComboBox *m_displayModeCombo;
QComboBox *m_pivotCombo; // Focused/Other pivot
CompactMailDelegate *m_compactDelegate = nullptr;
bool m_compactMode = false;
int m_compactThreshold = 650;
+2
View File
@@ -388,6 +388,8 @@ void MainMainWindow::onFolderSelected(const QModelIndex &index)
Account* account = m_accountService->findAccountById(folder.accountId());
if (account) {
m_mailService->fetchMails(QString::number(account->id()), QString::number(m_currentFolderId));
// Tell MailListView the folder type for Focused/Other pivot
m_mailListView->setFolderType(folder.type().toLower()); // "inbox", "sent", etc.
delete account;
}
}