feat: Multi-selection + action bar in MailListView

- MailListView: ExtendedSelection mode for both tree and list views
- Action bar (blue bar) appears when items selected
- Select all checkbox + counter label
- Batch actions: Flag, Mark unread, Move (TODO), Delete, Exit selection
- Signals: selectionChanged, batchFlagRequested, batchDeleteRequested, batchMarkUnreadRequested, batchMoveRequested
- enterMultiSelectMode()/exitMultiSelectMode() state management
- Works in both normal and compact views
This commit is contained in:
2026-08-26 02:38:33 +02:00
parent 3846bd4e9d
commit 43b828fe87
11 changed files with 11023 additions and 10653 deletions
@@ -27264,6 +27264,7 @@ CMakeFiles/wino-mail-qt.dir/src/ui/delegates/CompactMailDelegate.cpp.o
/usr/include/x86_64-linux-gnu/qt6/QtGui/QFontMetrics /usr/include/x86_64-linux-gnu/qt6/QtGui/QFontMetrics
/usr/include/x86_64-linux-gnu/qt6/QtGui/QMouseEvent /usr/include/x86_64-linux-gnu/qt6/QtGui/QMouseEvent
/usr/include/x86_64-linux-gnu/qt6/QtGui/QPainter /usr/include/x86_64-linux-gnu/qt6/QtGui/QPainter
/usr/include/x86_64-linux-gnu/qt6/QtGui/QPainterPath
/usr/include/x86_64-linux-gnu/qt6/QtGui/QPixmap /usr/include/x86_64-linux-gnu/qt6/QtGui/QPixmap
/usr/include/x86_64-linux-gnu/qt6/QtGui/QTransform /usr/include/x86_64-linux-gnu/qt6/QtGui/QTransform
/usr/include/x86_64-linux-gnu/qt6/QtGui/qaction.h /usr/include/x86_64-linux-gnu/qt6/QtGui/qaction.h
@@ -27286,6 +27287,7 @@ CMakeFiles/wino-mail-qt.dir/src/ui/delegates/CompactMailDelegate.cpp.o
/usr/include/x86_64-linux-gnu/qt6/QtGui/qkeysequence.h /usr/include/x86_64-linux-gnu/qt6/QtGui/qkeysequence.h
/usr/include/x86_64-linux-gnu/qt6/QtGui/qpaintdevice.h /usr/include/x86_64-linux-gnu/qt6/QtGui/qpaintdevice.h
/usr/include/x86_64-linux-gnu/qt6/QtGui/qpainter.h /usr/include/x86_64-linux-gnu/qt6/QtGui/qpainter.h
/usr/include/x86_64-linux-gnu/qt6/QtGui/qpainterpath.h
/usr/include/x86_64-linux-gnu/qt6/QtGui/qpalette.h /usr/include/x86_64-linux-gnu/qt6/QtGui/qpalette.h
/usr/include/x86_64-linux-gnu/qt6/QtGui/qpen.h /usr/include/x86_64-linux-gnu/qt6/QtGui/qpen.h
/usr/include/x86_64-linux-gnu/qt6/QtGui/qpixelformat.h /usr/include/x86_64-linux-gnu/qt6/QtGui/qpixelformat.h
@@ -28586,12 +28588,14 @@ CMakeFiles/wino-mail-qt.dir/src/ui/maillistview.cpp.o
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QLabel /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QLabel
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QLineEdit /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QLineEdit
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QListView /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QListView
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QMenu
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QPushButton /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QPushButton
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QScrollBar /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QScrollBar
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QStackedWidget /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QStackedWidget
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QStyle /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QStyle
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QStyleOptionViewItem /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QStyleOptionViewItem
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QStyledItemDelegate /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QStyledItemDelegate
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QToolButton
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QTreeView /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QTreeView
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QVBoxLayout /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QVBoxLayout
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QWidget /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QWidget
@@ -28613,6 +28617,7 @@ CMakeFiles/wino-mail-qt.dir/src/ui/maillistview.cpp.o
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qlayoutitem.h /usr/include/x86_64-linux-gnu/qt6/QtWidgets/qlayoutitem.h
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qlineedit.h /usr/include/x86_64-linux-gnu/qt6/QtWidgets/qlineedit.h
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qlistview.h /usr/include/x86_64-linux-gnu/qt6/QtWidgets/qlistview.h
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qmenu.h
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qpushbutton.h /usr/include/x86_64-linux-gnu/qt6/QtWidgets/qpushbutton.h
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qrubberband.h /usr/include/x86_64-linux-gnu/qt6/QtWidgets/qrubberband.h
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qscrollbar.h /usr/include/x86_64-linux-gnu/qt6/QtWidgets/qscrollbar.h
@@ -28624,6 +28629,7 @@ CMakeFiles/wino-mail-qt.dir/src/ui/maillistview.cpp.o
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qstyleoption.h /usr/include/x86_64-linux-gnu/qt6/QtWidgets/qstyleoption.h
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qtabbar.h /usr/include/x86_64-linux-gnu/qt6/QtWidgets/qtabbar.h
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qtabwidget.h /usr/include/x86_64-linux-gnu/qt6/QtWidgets/qtabwidget.h
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qtoolbutton.h
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qtreeview.h /usr/include/x86_64-linux-gnu/qt6/QtWidgets/qtreeview.h
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qtwidgets-config.h /usr/include/x86_64-linux-gnu/qt6/QtWidgets/qtwidgets-config.h
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qtwidgetsexports.h /usr/include/x86_64-linux-gnu/qt6/QtWidgets/qtwidgetsexports.h
@@ -27216,6 +27216,7 @@ CMakeFiles/wino-mail-qt.dir/src/ui/delegates/CompactMailDelegate.cpp.o: /mnt/c/U
/usr/include/x86_64-linux-gnu/qt6/QtGui/QFontMetrics \ /usr/include/x86_64-linux-gnu/qt6/QtGui/QFontMetrics \
/usr/include/x86_64-linux-gnu/qt6/QtGui/QMouseEvent \ /usr/include/x86_64-linux-gnu/qt6/QtGui/QMouseEvent \
/usr/include/x86_64-linux-gnu/qt6/QtGui/QPainter \ /usr/include/x86_64-linux-gnu/qt6/QtGui/QPainter \
/usr/include/x86_64-linux-gnu/qt6/QtGui/QPainterPath \
/usr/include/x86_64-linux-gnu/qt6/QtGui/QPixmap \ /usr/include/x86_64-linux-gnu/qt6/QtGui/QPixmap \
/usr/include/x86_64-linux-gnu/qt6/QtGui/QTransform \ /usr/include/x86_64-linux-gnu/qt6/QtGui/QTransform \
/usr/include/x86_64-linux-gnu/qt6/QtGui/qaction.h \ /usr/include/x86_64-linux-gnu/qt6/QtGui/qaction.h \
@@ -27238,6 +27239,7 @@ CMakeFiles/wino-mail-qt.dir/src/ui/delegates/CompactMailDelegate.cpp.o: /mnt/c/U
/usr/include/x86_64-linux-gnu/qt6/QtGui/qkeysequence.h \ /usr/include/x86_64-linux-gnu/qt6/QtGui/qkeysequence.h \
/usr/include/x86_64-linux-gnu/qt6/QtGui/qpaintdevice.h \ /usr/include/x86_64-linux-gnu/qt6/QtGui/qpaintdevice.h \
/usr/include/x86_64-linux-gnu/qt6/QtGui/qpainter.h \ /usr/include/x86_64-linux-gnu/qt6/QtGui/qpainter.h \
/usr/include/x86_64-linux-gnu/qt6/QtGui/qpainterpath.h \
/usr/include/x86_64-linux-gnu/qt6/QtGui/qpalette.h \ /usr/include/x86_64-linux-gnu/qt6/QtGui/qpalette.h \
/usr/include/x86_64-linux-gnu/qt6/QtGui/qpen.h \ /usr/include/x86_64-linux-gnu/qt6/QtGui/qpen.h \
/usr/include/x86_64-linux-gnu/qt6/QtGui/qpixelformat.h \ /usr/include/x86_64-linux-gnu/qt6/QtGui/qpixelformat.h \
@@ -28536,12 +28538,14 @@ CMakeFiles/wino-mail-qt.dir/src/ui/maillistview.cpp.o: /mnt/c/Users/javie/Docume
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QLabel \ /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QLabel \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QLineEdit \ /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QLineEdit \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QListView \ /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QListView \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QMenu \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QPushButton \ /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QPushButton \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QScrollBar \ /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QScrollBar \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QStackedWidget \ /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QStackedWidget \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QStyle \ /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QStyle \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QStyleOptionViewItem \ /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QStyleOptionViewItem \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QStyledItemDelegate \ /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QStyledItemDelegate \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QToolButton \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QTreeView \ /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QTreeView \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QVBoxLayout \ /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QVBoxLayout \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QWidget \ /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QWidget \
@@ -28563,6 +28567,7 @@ CMakeFiles/wino-mail-qt.dir/src/ui/maillistview.cpp.o: /mnt/c/Users/javie/Docume
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qlayoutitem.h \ /usr/include/x86_64-linux-gnu/qt6/QtWidgets/qlayoutitem.h \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qlineedit.h \ /usr/include/x86_64-linux-gnu/qt6/QtWidgets/qlineedit.h \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qlistview.h \ /usr/include/x86_64-linux-gnu/qt6/QtWidgets/qlistview.h \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qmenu.h \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qpushbutton.h \ /usr/include/x86_64-linux-gnu/qt6/QtWidgets/qpushbutton.h \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qrubberband.h \ /usr/include/x86_64-linux-gnu/qt6/QtWidgets/qrubberband.h \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qscrollbar.h \ /usr/include/x86_64-linux-gnu/qt6/QtWidgets/qscrollbar.h \
@@ -28574,6 +28579,7 @@ CMakeFiles/wino-mail-qt.dir/src/ui/maillistview.cpp.o: /mnt/c/Users/javie/Docume
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qstyleoption.h \ /usr/include/x86_64-linux-gnu/qt6/QtWidgets/qstyleoption.h \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qtabbar.h \ /usr/include/x86_64-linux-gnu/qt6/QtWidgets/qtabbar.h \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qtabwidget.h \ /usr/include/x86_64-linux-gnu/qt6/QtWidgets/qtabwidget.h \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qtoolbutton.h \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qtreeview.h \ /usr/include/x86_64-linux-gnu/qt6/QtWidgets/qtreeview.h \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qtwidgets-config.h \ /usr/include/x86_64-linux-gnu/qt6/QtWidgets/qtwidgets-config.h \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qtwidgetsexports.h \ /usr/include/x86_64-linux-gnu/qt6/QtWidgets/qtwidgetsexports.h \
@@ -42679,8 +42685,6 @@ CMakeFiles/wino-mail-qt.dir/src/core/oauthcallbackserver.cpp.o:
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QStyleOptionFrame: /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QStyleOptionFrame:
/usr/include/x86_64-linux-gnu/qt6/QtGui/qpainterpath.h:
/usr/include/x86_64-linux-gnu/qt6/QtGui/QKeyEvent: /usr/include/x86_64-linux-gnu/qt6/QtGui/QKeyEvent:
/mnt/c/Users/javie/Documents/Codex/2026-08-11/revisar-2/wino-mail-dtkqt/thirdparty/tags/src/util.hpp: /mnt/c/Users/javie/Documents/Codex/2026-08-11/revisar-2/wino-mail-dtkqt/thirdparty/tags/src/util.hpp:
@@ -42731,6 +42735,8 @@ wino-mail-qt_autogen/GQ6NBGVJMG/moc_accountservice.cpp:
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QScrollBar: /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QScrollBar:
/usr/include/x86_64-linux-gnu/qt6/QtGui/qpainterpath.h:
/usr/include/x86_64-linux-gnu/qt6/QtGui/QCursor: /usr/include/x86_64-linux-gnu/qt6/QtGui/QCursor:
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qfiledialog.h: /usr/include/x86_64-linux-gnu/qt6/QtWidgets/qfiledialog.h:
@@ -598,4 +598,8 @@ CMakeFiles/wino-mail-qt.dir/src/ui/maillistview.cpp.o: \
/usr/include/x86_64-linux-gnu/qt6/QtGui/qcolor.h \ /usr/include/x86_64-linux-gnu/qt6/QtGui/qcolor.h \
/usr/include/x86_64-linux-gnu/qt6/QtCore/QRect \ /usr/include/x86_64-linux-gnu/qt6/QtCore/QRect \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QScrollBar \ /usr/include/x86_64-linux-gnu/qt6/QtWidgets/QScrollBar \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qscrollbar.h /usr/include/x86_64-linux-gnu/qt6/QtWidgets/qscrollbar.h \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QToolButton \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qtoolbutton.h \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/QMenu \
/usr/include/x86_64-linux-gnu/qt6/QtWidgets/qmenu.h
File diff suppressed because it is too large Load Diff
Binary file not shown.
@@ -9,6 +9,7 @@
#include "../../../src/ui/maillistview.h" #include "../../../src/ui/maillistview.h"
#include <QtGui/qtextcursor.h> #include <QtGui/qtextcursor.h>
#include <QtCore/qmetatype.h> #include <QtCore/qmetatype.h>
#include <QtCore/QList>
#include <QtCore/qtmochelpers.h> #include <QtCore/qtmochelpers.h>
@@ -54,6 +55,16 @@ template <> constexpr inline auto MailListView::qt_create_metaobjectdata<qt_meta
"replyRequested", "replyRequested",
"forwardRequested", "forwardRequested",
"markUnreadRequested", "markUnreadRequested",
"selectionChanged",
"QList<int>",
"selectedMailIds",
"batchFlagRequested",
"mailIds",
"flagged",
"batchDeleteRequested",
"batchMarkUnreadRequested",
"batchMoveRequested",
"targetFolderId",
"onRowSelected", "onRowSelected",
"QModelIndex", "QModelIndex",
"index", "index",
@@ -78,7 +89,16 @@ template <> constexpr inline auto MailListView::qt_create_metaobjectdata<qt_meta
"onRowsInserted", "onRowsInserted",
"parent", "parent",
"first", "first",
"last" "last",
"onSelectionChanged",
"onSelectAllToggled",
"checked",
"onBatchFlagClicked",
"onBatchMarkUnreadClicked",
"onBatchMoveClicked",
"onBatchDeleteClicked",
"enterMultiSelectMode",
"exitMultiSelectMode"
}; };
QtMocHelpers::UintData qt_methods { QtMocHelpers::UintData qt_methods {
@@ -120,72 +140,110 @@ template <> constexpr inline auto MailListView::qt_create_metaobjectdata<qt_meta
QtMocHelpers::SignalData<void(int)>(14, 2, QMC::AccessPublic, QMetaType::Void, {{ QtMocHelpers::SignalData<void(int)>(14, 2, QMC::AccessPublic, QMetaType::Void, {{
{ QMetaType::Int, 3 }, { QMetaType::Int, 3 },
}}), }}),
// Slot 'onRowSelected' // Signal 'selectionChanged'
QtMocHelpers::SlotData<void(const QModelIndex &)>(15, 2, QMC::AccessPrivate, QMetaType::Void, {{ QtMocHelpers::SignalData<void(const QVector<int> &)>(15, 2, QMC::AccessPublic, QMetaType::Void, {{
{ 0x80000000 | 16, 17 }, { 0x80000000 | 16, 17 },
}}), }}),
// Signal 'batchFlagRequested'
QtMocHelpers::SignalData<void(const QVector<int> &, bool)>(18, 2, QMC::AccessPublic, QMetaType::Void, {{
{ 0x80000000 | 16, 19 }, { QMetaType::Bool, 20 },
}}),
// Signal 'batchDeleteRequested'
QtMocHelpers::SignalData<void(const QVector<int> &)>(21, 2, QMC::AccessPublic, QMetaType::Void, {{
{ 0x80000000 | 16, 19 },
}}),
// Signal 'batchMarkUnreadRequested'
QtMocHelpers::SignalData<void(const QVector<int> &)>(22, 2, QMC::AccessPublic, QMetaType::Void, {{
{ 0x80000000 | 16, 19 },
}}),
// Signal 'batchMoveRequested'
QtMocHelpers::SignalData<void(const QVector<int> &, int)>(23, 2, QMC::AccessPublic, QMetaType::Void, {{
{ 0x80000000 | 16, 19 }, { QMetaType::Int, 24 },
}}),
// Slot 'onRowSelected'
QtMocHelpers::SlotData<void(const QModelIndex &)>(25, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ 0x80000000 | 26, 27 },
}}),
// Slot 'onSearchTextChanged' // Slot 'onSearchTextChanged'
QtMocHelpers::SlotData<void(const QString &)>(18, 2, QMC::AccessPrivate, QMetaType::Void, {{ QtMocHelpers::SlotData<void(const QString &)>(28, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::QString, 19 }, { QMetaType::QString, 29 },
}}), }}),
// Slot 'onFilterChanged' // Slot 'onFilterChanged'
QtMocHelpers::SlotData<void()>(20, 2, QMC::AccessPrivate, QMetaType::Void), QtMocHelpers::SlotData<void()>(30, 2, QMC::AccessPrivate, QMetaType::Void),
// Slot 'onGroupByChanged' // Slot 'onGroupByChanged'
QtMocHelpers::SlotData<void(int)>(21, 2, QMC::AccessPrivate, QMetaType::Void, {{ QtMocHelpers::SlotData<void(int)>(31, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 17 }, { QMetaType::Int, 27 },
}}), }}),
// Slot 'onCompactFlagRequested' // Slot 'onCompactFlagRequested'
QtMocHelpers::SlotData<void(int)>(22, 2, QMC::AccessPrivate, QMetaType::Void, {{ QtMocHelpers::SlotData<void(int)>(32, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 3 }, { QMetaType::Int, 3 },
}}), }}),
// Slot 'onCompactDeleteRequested' // Slot 'onCompactDeleteRequested'
QtMocHelpers::SlotData<void(int)>(23, 2, QMC::AccessPrivate, QMetaType::Void, {{ QtMocHelpers::SlotData<void(int)>(33, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 3 }, { QMetaType::Int, 3 },
}}), }}),
// Slot 'onCompactCategoryRequested' // Slot 'onCompactCategoryRequested'
QtMocHelpers::SlotData<void(int)>(24, 2, QMC::AccessPrivate, QMetaType::Void, {{ QtMocHelpers::SlotData<void(int)>(34, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 3 }, { QMetaType::Int, 3 },
}}), }}),
// Slot 'onCompactMoreRequested' // Slot 'onCompactMoreRequested'
QtMocHelpers::SlotData<void(int, const QPoint &)>(25, 2, QMC::AccessPrivate, QMetaType::Void, {{ QtMocHelpers::SlotData<void(int, const QPoint &)>(35, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 3 }, { 0x80000000 | 10, 11 }, { QMetaType::Int, 3 }, { 0x80000000 | 10, 11 },
}}), }}),
// Slot 'onCompactMailClicked' // Slot 'onCompactMailClicked'
QtMocHelpers::SlotData<void(int)>(26, 2, QMC::AccessPrivate, QMetaType::Void, {{ QtMocHelpers::SlotData<void(int)>(36, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 3 }, { QMetaType::Int, 3 },
}}), }}),
// Slot 'onCompactReplyRequested' // Slot 'onCompactReplyRequested'
QtMocHelpers::SlotData<void(int)>(27, 2, QMC::AccessPrivate, QMetaType::Void, {{ QtMocHelpers::SlotData<void(int)>(37, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 3 }, { QMetaType::Int, 3 },
}}), }}),
// Slot 'onCompactForwardRequested' // Slot 'onCompactForwardRequested'
QtMocHelpers::SlotData<void(int)>(28, 2, QMC::AccessPrivate, QMetaType::Void, {{ QtMocHelpers::SlotData<void(int)>(38, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 3 }, { QMetaType::Int, 3 },
}}), }}),
// Slot 'onCompactMarkUnreadRequested' // Slot 'onCompactMarkUnreadRequested'
QtMocHelpers::SlotData<void(int)>(29, 2, QMC::AccessPrivate, QMetaType::Void, {{ QtMocHelpers::SlotData<void(int)>(39, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 3 }, { QMetaType::Int, 3 },
}}), }}),
// Slot 'onDisplayModeChanged' // Slot 'onDisplayModeChanged'
QtMocHelpers::SlotData<void(int)>(30, 2, QMC::AccessPrivate, QMetaType::Void, {{ QtMocHelpers::SlotData<void(int)>(40, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 17 }, { QMetaType::Int, 27 },
}}), }}),
// Slot 'onTotalCountChanged' // Slot 'onTotalCountChanged'
QtMocHelpers::SlotData<void(int)>(31, 2, QMC::AccessPrivate, QMetaType::Void, {{ QtMocHelpers::SlotData<void(int)>(41, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 32 }, { QMetaType::Int, 42 },
}}), }}),
// Slot 'onTreeViewScrolled' // Slot 'onTreeViewScrolled'
QtMocHelpers::SlotData<void(int)>(33, 2, QMC::AccessPrivate, QMetaType::Void, {{ QtMocHelpers::SlotData<void(int)>(43, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 34 }, { QMetaType::Int, 44 },
}}), }}),
// Slot 'onListViewScrolled' // Slot 'onListViewScrolled'
QtMocHelpers::SlotData<void(int)>(35, 2, QMC::AccessPrivate, QMetaType::Void, {{ QtMocHelpers::SlotData<void(int)>(45, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Int, 34 }, { QMetaType::Int, 44 },
}}), }}),
// Slot 'onRowsInserted' // Slot 'onRowsInserted'
QtMocHelpers::SlotData<void(const QModelIndex &, int, int)>(36, 2, QMC::AccessPrivate, QMetaType::Void, {{ QtMocHelpers::SlotData<void(const QModelIndex &, int, int)>(46, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ 0x80000000 | 16, 37 }, { QMetaType::Int, 38 }, { QMetaType::Int, 39 }, { 0x80000000 | 26, 47 }, { QMetaType::Int, 48 }, { QMetaType::Int, 49 },
}}), }}),
// Slot 'onSelectionChanged'
QtMocHelpers::SlotData<void()>(50, 2, QMC::AccessPrivate, QMetaType::Void),
// Slot 'onSelectAllToggled'
QtMocHelpers::SlotData<void(bool)>(51, 2, QMC::AccessPrivate, QMetaType::Void, {{
{ QMetaType::Bool, 52 },
}}),
// 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'
QtMocHelpers::SlotData<void()>(56, 2, QMC::AccessPrivate, QMetaType::Void),
// Slot 'enterMultiSelectMode'
QtMocHelpers::SlotData<void()>(57, 2, QMC::AccessPrivate, QMetaType::Void),
// Slot 'exitMultiSelectMode'
QtMocHelpers::SlotData<void()>(58, 2, QMC::AccessPrivate, QMetaType::Void),
}; };
QtMocHelpers::UintData qt_properties { QtMocHelpers::UintData qt_properties {
}; };
@@ -219,26 +277,79 @@ void MailListView::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id
case 7: _t->replyRequested((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break; case 7: _t->replyRequested((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 8: _t->forwardRequested((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break; case 8: _t->forwardRequested((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 9: _t->markUnreadRequested((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break; case 9: _t->markUnreadRequested((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 10: _t->onRowSelected((*reinterpret_cast<std::add_pointer_t<QModelIndex>>(_a[1]))); break; case 10: _t->selectionChanged((*reinterpret_cast<std::add_pointer_t<QList<int>>>(_a[1]))); break;
case 11: _t->onSearchTextChanged((*reinterpret_cast<std::add_pointer_t<QString>>(_a[1]))); break; case 11: _t->batchFlagRequested((*reinterpret_cast<std::add_pointer_t<QList<int>>>(_a[1])),(*reinterpret_cast<std::add_pointer_t<bool>>(_a[2]))); break;
case 12: _t->onFilterChanged(); break; case 12: _t->batchDeleteRequested((*reinterpret_cast<std::add_pointer_t<QList<int>>>(_a[1]))); break;
case 13: _t->onGroupByChanged((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break; case 13: _t->batchMarkUnreadRequested((*reinterpret_cast<std::add_pointer_t<QList<int>>>(_a[1]))); break;
case 14: _t->onCompactFlagRequested((*reinterpret_cast<std::add_pointer_t<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->onCompactDeleteRequested((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break; case 15: _t->onRowSelected((*reinterpret_cast<std::add_pointer_t<QModelIndex>>(_a[1]))); break;
case 16: _t->onCompactCategoryRequested((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break; case 16: _t->onSearchTextChanged((*reinterpret_cast<std::add_pointer_t<QString>>(_a[1]))); break;
case 17: _t->onCompactMoreRequested((*reinterpret_cast<std::add_pointer_t<int>>(_a[1])),(*reinterpret_cast<std::add_pointer_t<QPoint>>(_a[2]))); break; case 17: _t->onFilterChanged(); break;
case 18: _t->onCompactMailClicked((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break; case 18: _t->onGroupByChanged((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break;
case 19: _t->onCompactReplyRequested((*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->onCompactForwardRequested((*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->onCompactMarkUnreadRequested((*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->onDisplayModeChanged((*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->onTotalCountChanged((*reinterpret_cast<std::add_pointer_t<int>>(_a[1]))); break; case 23: _t->onCompactMailClicked((*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 24: _t->onCompactReplyRequested((*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 25: _t->onCompactForwardRequested((*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; 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;
default: ; default: ;
} }
} }
if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
switch (_id) {
default: *reinterpret_cast<QMetaType *>(_a[0]) = QMetaType(); break;
case 10:
switch (*reinterpret_cast<int*>(_a[1])) {
default: *reinterpret_cast<QMetaType *>(_a[0]) = QMetaType(); break;
case 0:
*reinterpret_cast<QMetaType *>(_a[0]) = QMetaType::fromType< QList<int> >(); break;
}
break;
case 11:
switch (*reinterpret_cast<int*>(_a[1])) {
default: *reinterpret_cast<QMetaType *>(_a[0]) = QMetaType(); break;
case 0:
*reinterpret_cast<QMetaType *>(_a[0]) = QMetaType::fromType< QList<int> >(); break;
}
break;
case 12:
switch (*reinterpret_cast<int*>(_a[1])) {
default: *reinterpret_cast<QMetaType *>(_a[0]) = QMetaType(); break;
case 0:
*reinterpret_cast<QMetaType *>(_a[0]) = QMetaType::fromType< QList<int> >(); break;
}
break;
case 13:
switch (*reinterpret_cast<int*>(_a[1])) {
default: *reinterpret_cast<QMetaType *>(_a[0]) = QMetaType(); break;
case 0:
*reinterpret_cast<QMetaType *>(_a[0]) = QMetaType::fromType< QList<int> >(); break;
}
break;
case 14:
switch (*reinterpret_cast<int*>(_a[1])) {
default: *reinterpret_cast<QMetaType *>(_a[0]) = QMetaType(); break;
case 0:
*reinterpret_cast<QMetaType *>(_a[0]) = QMetaType::fromType< QList<int> >(); break;
}
break;
}
}
if (_c == QMetaObject::IndexOfMethod) { if (_c == QMetaObject::IndexOfMethod) {
if (QtMocHelpers::indexOfMethod<void (MailListView::*)(int )>(_a, &MailListView::emailSelected, 0)) if (QtMocHelpers::indexOfMethod<void (MailListView::*)(int )>(_a, &MailListView::emailSelected, 0))
return; return;
@@ -260,6 +371,16 @@ void MailListView::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id
return; return;
if (QtMocHelpers::indexOfMethod<void (MailListView::*)(int )>(_a, &MailListView::markUnreadRequested, 9)) if (QtMocHelpers::indexOfMethod<void (MailListView::*)(int )>(_a, &MailListView::markUnreadRequested, 9))
return; return;
if (QtMocHelpers::indexOfMethod<void (MailListView::*)(const QVector<int> & )>(_a, &MailListView::selectionChanged, 10))
return;
if (QtMocHelpers::indexOfMethod<void (MailListView::*)(const QVector<int> & , bool )>(_a, &MailListView::batchFlagRequested, 11))
return;
if (QtMocHelpers::indexOfMethod<void (MailListView::*)(const QVector<int> & )>(_a, &MailListView::batchDeleteRequested, 12))
return;
if (QtMocHelpers::indexOfMethod<void (MailListView::*)(const QVector<int> & )>(_a, &MailListView::batchMarkUnreadRequested, 13))
return;
if (QtMocHelpers::indexOfMethod<void (MailListView::*)(const QVector<int> & , int )>(_a, &MailListView::batchMoveRequested, 14))
return;
} }
} }
@@ -282,14 +403,14 @@ int MailListView::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
if (_id < 0) if (_id < 0)
return _id; return _id;
if (_c == QMetaObject::InvokeMetaMethod) { if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 27) if (_id < 40)
qt_static_metacall(this, _c, _id, _a); qt_static_metacall(this, _c, _id, _a);
_id -= 27; _id -= 40;
} }
if (_c == QMetaObject::RegisterMethodArgumentMetaType) { if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 27) if (_id < 40)
*reinterpret_cast<QMetaType *>(_a[0]) = QMetaType(); qt_static_metacall(this, _c, _id, _a);
_id -= 27; _id -= 40;
} }
return _id; return _id;
} }
@@ -353,4 +474,34 @@ void MailListView::markUnreadRequested(int _t1)
{ {
QMetaObject::activate<void>(this, &staticMetaObject, 9, nullptr, _t1); QMetaObject::activate<void>(this, &staticMetaObject, 9, nullptr, _t1);
} }
// SIGNAL 10
void MailListView::selectionChanged(const QVector<int> & _t1)
{
QMetaObject::activate<void>(this, &staticMetaObject, 10, nullptr, _t1);
}
// SIGNAL 11
void MailListView::batchFlagRequested(const QVector<int> & _t1, bool _t2)
{
QMetaObject::activate<void>(this, &staticMetaObject, 11, nullptr, _t1, _t2);
}
// SIGNAL 12
void MailListView::batchDeleteRequested(const QVector<int> & _t1)
{
QMetaObject::activate<void>(this, &staticMetaObject, 12, nullptr, _t1);
}
// SIGNAL 13
void MailListView::batchMarkUnreadRequested(const QVector<int> & _t1)
{
QMetaObject::activate<void>(this, &staticMetaObject, 13, nullptr, _t1);
}
// SIGNAL 14
void MailListView::batchMoveRequested(const QVector<int> & _t1, int _t2)
{
QMetaObject::activate<void>(this, &staticMetaObject, 14, nullptr, _t1, _t2);
}
QT_WARNING_POP QT_WARNING_POP
+233 -50
View File
@@ -15,9 +15,11 @@
#include <QListView> #include <QListView>
#include <QStyledItemDelegate> #include <QStyledItemDelegate>
#include <QScrollBar> #include <QScrollBar>
#include <QToolButton>
#include <QMenu>
#include "ui/delegates/CompactMailDelegate.h" #include "ui/delegates/CompactMailDelegate.h"
MailListView::MailListView(QWidget *parent) : QWidget(parent), m_sourceModel(nullptr) MailListView::MailListView(QWidget *parent) : QWidget(parent), m_sourceModel(nullptr), m_multiSelectMode(false)
{ {
setupUI(); setupUI();
} }
@@ -110,6 +112,67 @@ void MailListView::setupUI()
layout->addWidget(filterBar); layout->addWidget(filterBar);
// Action bar (hidden by default, shown when multi-select mode active)
m_actionBar = new QWidget();
m_actionBar->setFixedHeight(44);
m_actionBar->setStyleSheet("background-color: #e3f2fd; border-bottom: 1px solid #bbdefb;");
m_actionBar->setVisible(false);
QHBoxLayout *actionBarLayout = new QHBoxLayout(m_actionBar);
actionBarLayout->setContentsMargins(12, 4, 12, 4);
actionBarLayout->setSpacing(8);
m_selectAllCheck = new QCheckBox("Seleccionar todo");
m_selectAllCheck->setStyleSheet("QCheckBox { font-size: 13px; color: #1d1d1f; }");
connect(m_selectAllCheck, &QCheckBox::toggled, this, &MailListView::onSelectAllToggled);
actionBarLayout->addWidget(m_selectAllCheck);
QLabel *selectionLabel = new QLabel("0 elementos seleccionados");
selectionLabel->setStyleSheet("font-size: 13px; color: #1d1d1f; font-weight: 500;");
selectionLabel->setObjectName("selectionLabel");
actionBarLayout->addWidget(selectionLabel);
actionBarLayout->addStretch();
// Action buttons
auto createActionButton = [&](const QString& text, std::function<void()> slot) -> QToolButton* {
QToolButton *btn = new QToolButton();
btn->setText(text);
btn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
btn->setStyleSheet(
"QToolButton { background: white; border: 1px solid #d1d1d6; border-radius: 6px; "
"padding: 6px 12px; font-size: 12px; color: #1d1d1f; }"
"QToolButton:hover { background: #f0f0f5; border-color: #bdbdbd; }"
"QToolButton:pressed { background: #e0e0e5; }"
);
connect(btn, &QToolButton::clicked, this, slot);
return btn;
};
QToolButton *btnFlag = createActionButton("★ Marcar", [this]() { onBatchFlagClicked(); });
actionBarLayout->addWidget(btnFlag);
QToolButton *btnUnread = createActionButton("✎ No leído", [this]() { onBatchMarkUnreadClicked(); });
actionBarLayout->addWidget(btnUnread);
QToolButton *btnMove = createActionButton("↗ Mover", [this]() { onBatchMoveClicked(); });
actionBarLayout->addWidget(btnMove);
QToolButton *btnDelete = createActionButton("🗑 Borrar", [this]() { onBatchDeleteClicked(); });
btnDelete->setStyleSheet(btnDelete->styleSheet() + "QToolButton { color: #ff3b30; border-color: #ff3b30; }");
actionBarLayout->addWidget(btnDelete);
QToolButton *btnExit = new QToolButton();
btnExit->setText("✕ Salir selección");
btnExit->setToolButtonStyle(Qt::ToolButtonTextOnly);
btnExit->setStyleSheet(
"QToolButton { padding: 6px 12px; font-size: 12px; color: #0071e3; }"
"QToolButton:hover { background: #e8f0fe; border-radius: 6px; }"
);
connect(btnExit, &QToolButton::clicked, this, [this]() { exitMultiSelectMode(); });
actionBarLayout->addWidget(btnExit);
layout->insertWidget(1, m_actionBar); // Insert after search bar
// View Stack (TreeView for normal, ListView for compact) // View Stack (TreeView for normal, ListView for compact)
m_viewStack = new QStackedWidget(); m_viewStack = new QStackedWidget();
layout->addWidget(m_viewStack, 1); layout->addWidget(m_viewStack, 1);
@@ -117,7 +180,7 @@ void MailListView::setupUI()
// --- Normal Tree View --- // --- Normal Tree View ---
m_treeView = new QTreeView(); m_treeView = new QTreeView();
m_treeView->setSelectionBehavior(QAbstractItemView::SelectRows); m_treeView->setSelectionBehavior(QAbstractItemView::SelectRows);
m_treeView->setSelectionMode(QAbstractItemView::SingleSelection); m_treeView->setSelectionMode(QAbstractItemView::ExtendedSelection); // Multi-selection
m_treeView->setAlternatingRowColors(true); m_treeView->setAlternatingRowColors(true);
m_treeView->header()->setStretchLastSection(false); m_treeView->header()->setStretchLastSection(false);
m_treeView->header()->setSectionsClickable(true); m_treeView->header()->setSectionsClickable(true);
@@ -146,7 +209,8 @@ void MailListView::setupUI()
m_treeView->header()->setSectionResizeMode(EmailTreeModel::ColSender, QHeaderView::Stretch); m_treeView->header()->setSectionResizeMode(EmailTreeModel::ColSender, QHeaderView::Stretch);
m_treeView->header()->setSectionResizeMode(EmailTreeModel::ColDate, QHeaderView::ResizeToContents); m_treeView->header()->setSectionResizeMode(EmailTreeModel::ColDate, QHeaderView::ResizeToContents);
connect(m_treeView, &QTreeView::clicked, this, &MailListView::onRowSelected); connect(m_treeView->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &MailListView::onSelectionChanged);
connect(m_treeView, &QTreeView::doubleClicked, this, [this](const QModelIndex &index) { connect(m_treeView, &QTreeView::doubleClicked, this, [this](const QModelIndex &index) {
if (!index.isValid()) return; if (!index.isValid()) return;
QModelIndex proxyIdx = m_proxyModel->mapToSource(index); QModelIndex proxyIdx = m_proxyModel->mapToSource(index);
@@ -172,7 +236,7 @@ void MailListView::setupUI()
// --- Compact List View --- // --- Compact List View ---
m_listView = new QListView(); m_listView = new QListView();
m_listView->setSelectionMode(QAbstractItemView::SingleSelection); m_listView->setSelectionMode(QAbstractItemView::ExtendedSelection); // Multi-selection
m_listView->setUniformItemSizes(true); m_listView->setUniformItemSizes(true);
m_listView->setFrameShape(QFrame::NoFrame); m_listView->setFrameShape(QFrame::NoFrame);
m_listView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); m_listView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
@@ -197,11 +261,20 @@ void MailListView::setupUI()
this, &MailListView::onCompactMoreRequested); this, &MailListView::onCompactMoreRequested);
connect(m_compactDelegate, &CompactMailDelegate::mailClicked, connect(m_compactDelegate, &CompactMailDelegate::mailClicked,
this, &MailListView::onCompactMailClicked); this, &MailListView::onCompactMailClicked);
connect(m_compactDelegate, &CompactMailDelegate::replyRequested,
this, &MailListView::onCompactReplyRequested);
connect(m_compactDelegate, &CompactMailDelegate::forwardRequested,
this, &MailListView::onCompactForwardRequested);
connect(m_compactDelegate, &CompactMailDelegate::markUnreadRequested,
this, &MailListView::onCompactMarkUnreadRequested);
// Same proxy model for list view (single column) // Same proxy model for list view (single column)
m_listView->setModel(m_proxyModel); m_listView->setModel(m_proxyModel);
m_listView->setModelColumn(0); // Use first column (subject) m_listView->setModelColumn(0); // Use first column (subject)
connect(m_listView->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &MailListView::onSelectionChanged);
// Add both views to stack // Add both views to stack
m_viewStack->addWidget(m_treeView); // index 0 = normal m_viewStack->addWidget(m_treeView); // index 0 = normal
m_viewStack->addWidget(m_listView); // index 1 = compact m_viewStack->addWidget(m_listView); // index 1 = compact
@@ -271,13 +344,82 @@ void MailListView::updateViewMode()
} }
} }
void MailListView::onRowSelected(const QModelIndex &index) QVector<int> MailListView::getSelectedMailIds() const
{ {
if (!index.isValid()) return; QVector<int> mailIds;
QModelIndex proxyIdx = m_proxyModel->mapToSource(index); QAbstractItemView *currentView = qobject_cast<QAbstractItemView*>(m_viewStack->currentWidget());
if (proxyIdx.isValid() && proxyIdx.data(EmailTreeModel::MailIdRole).isValid()) { QItemSelectionModel *selectionModel = currentView->selectionModel();
int mailId = proxyIdx.data(EmailTreeModel::MailIdRole).toInt();
emit emailSelected(mailId); if (!selectionModel) return mailIds;
QModelIndexList selectedIndexes = selectionModel->selectedRows();
for (const QModelIndex &proxyIdx : selectedIndexes) {
QModelIndex sourceIdx = m_proxyModel->mapToSource(proxyIdx);
if (sourceIdx.isValid() && sourceIdx.data(EmailTreeModel::MailIdRole).isValid()) {
int mailId = sourceIdx.data(EmailTreeModel::MailIdRole).toInt();
mailIds.append(mailId);
}
}
return mailIds;
}
void MailListView::updateActionBar()
{
QLabel *label = m_actionBar->findChild<QLabel*>("selectionLabel");
if (label) {
label->setText(QString("%1 elementos seleccionados").arg(m_selectedMailIds.size()));
}
m_selectAllCheck->blockSignals(true);
m_selectAllCheck->setChecked(m_selectedMailIds.size() > 0);
m_selectAllCheck->blockSignals(false);
}
void MailListView::onSelectionChanged()
{
m_selectedMailIds = getSelectedMailIds();
bool hasSelection = !m_selectedMailIds.isEmpty();
if (hasSelection && !m_multiSelectMode) {
enterMultiSelectMode();
} else if (!hasSelection && m_multiSelectMode) {
exitMultiSelectMode();
}
updateActionBar();
emit selectionChanged(m_selectedMailIds);
}
void MailListView::enterMultiSelectMode()
{
m_multiSelectMode = true;
m_actionBar->setVisible(true);
updateActionBar();
}
void MailListView::exitMultiSelectMode()
{
m_multiSelectMode = false;
m_selectedMailIds.clear();
m_actionBar->setVisible(false);
// Clear selections
m_treeView->clearSelection();
m_listView->clearSelection();
m_selectAllCheck->blockSignals(true);
m_selectAllCheck->setChecked(false);
m_selectAllCheck->blockSignals(false);
updateActionBar();
emit selectionChanged(QVector<int>());
}
void MailListView::onSelectAllToggled(bool checked)
{
QAbstractItemView *currentView = qobject_cast<QAbstractItemView*>(m_viewStack->currentWidget());
if (checked) {
currentView->selectAll();
} else {
currentView->clearSelection();
} }
} }
@@ -314,46 +456,6 @@ void MailListView::onGroupByChanged(int index)
m_treeView->expandAll(); m_treeView->expandAll();
} }
void MailListView::onCompactFlagRequested(int mailId)
{
emit flagRequested(mailId);
}
void MailListView::onCompactDeleteRequested(int mailId)
{
emit deleteRequested(mailId);
}
void MailListView::onCompactCategoryRequested(int mailId)
{
emit categoryRequested(mailId);
}
void MailListView::onCompactMoreRequested(int mailId, const QPoint &globalPos)
{
emit moreRequested(mailId, globalPos);
}
void MailListView::onCompactMailClicked(int mailId)
{
emit emailSelected(mailId);
}
void MailListView::onCompactReplyRequested(int mailId)
{
emit replyRequested(mailId);
}
void MailListView::onCompactForwardRequested(int mailId)
{
emit forwardRequested(mailId);
}
void MailListView::onCompactMarkUnreadRequested(int mailId)
{
emit markUnreadRequested(mailId);
}
void MailListView::onDisplayModeChanged(int index) void MailListView::onDisplayModeChanged(int index)
{ {
CompactMailDelegate::DisplayMode mode = static_cast<CompactMailDelegate::DisplayMode>(index); CompactMailDelegate::DisplayMode mode = static_cast<CompactMailDelegate::DisplayMode>(index);
@@ -399,3 +501,84 @@ void MailListView::onRowsInserted(const QModelIndex &parent, int first, int last
m_treeView->expandAll(); m_treeView->expandAll();
} }
} }
void MailListView::onRowSelected(const QModelIndex &index)
{
if (!index.isValid()) return;
QModelIndex proxyIdx = m_proxyModel->mapToSource(index);
if (proxyIdx.isValid() && proxyIdx.data(EmailTreeModel::MailIdRole).isValid()) {
int mailId = proxyIdx.data(EmailTreeModel::MailIdRole).toInt();
emit emailSelected(mailId);
}
}
void MailListView::onCompactFlagRequested(int mailId)
{
emit flagRequested(mailId);
}
void MailListView::onCompactDeleteRequested(int mailId)
{
emit deleteRequested(mailId);
}
void MailListView::onCompactCategoryRequested(int mailId)
{
emit categoryRequested(mailId);
}
void MailListView::onCompactMoreRequested(int mailId, const QPoint &globalPos)
{
emit moreRequested(mailId, globalPos);
}
void MailListView::onCompactMailClicked(int mailId)
{
emit emailSelected(mailId);
}
void MailListView::onCompactReplyRequested(int mailId)
{
emit replyRequested(mailId);
}
void MailListView::onCompactForwardRequested(int mailId)
{
emit forwardRequested(mailId);
}
void MailListView::onCompactMarkUnreadRequested(int mailId)
{
emit markUnreadRequested(mailId);
}
// Batch action slots
void MailListView::onBatchFlagClicked()
{
if (m_selectedMailIds.isEmpty()) return;
emit batchFlagRequested(m_selectedMailIds, true);
exitMultiSelectMode();
}
void MailListView::onBatchMarkUnreadClicked()
{
if (m_selectedMailIds.isEmpty()) return;
emit batchMarkUnreadRequested(m_selectedMailIds);
exitMultiSelectMode();
}
void MailListView::onBatchMoveClicked()
{
if (m_selectedMailIds.isEmpty()) return;
// TODO: Show folder picker dialog
// For now, just emit signal
// emit batchMoveRequested(m_selectedMailIds, targetFolderId);
exitMultiSelectMode();
}
void MailListView::onBatchDeleteClicked()
{
if (m_selectedMailIds.isEmpty()) return;
emit batchDeleteRequested(m_selectedMailIds);
exitMultiSelectMode();
}
+20
View File
@@ -41,6 +41,12 @@ signals:
void replyRequested(int mailId); void replyRequested(int mailId);
void forwardRequested(int mailId); void forwardRequested(int mailId);
void markUnreadRequested(int mailId); void markUnreadRequested(int mailId);
// Multi-selection signals
void selectionChanged(const QVector<int>& selectedMailIds);
void batchFlagRequested(const QVector<int>& mailIds, bool flagged);
void batchDeleteRequested(const QVector<int>& mailIds);
void batchMarkUnreadRequested(const QVector<int>& mailIds);
void batchMoveRequested(const QVector<int>& mailIds, int targetFolderId);
private slots: private slots:
void onRowSelected(const QModelIndex &index); void onRowSelected(const QModelIndex &index);
@@ -60,6 +66,14 @@ private slots:
void onTreeViewScrolled(int value); void onTreeViewScrolled(int value);
void onListViewScrolled(int value); void onListViewScrolled(int value);
void onRowsInserted(const QModelIndex &parent, int first, int last); void onRowsInserted(const QModelIndex &parent, int first, int last);
void onSelectionChanged();
void onSelectAllToggled(bool checked);
void onBatchFlagClicked();
void onBatchMarkUnreadClicked();
void onBatchMoveClicked();
void onBatchDeleteClicked();
void enterMultiSelectMode();
void exitMultiSelectMode();
protected: protected:
void resizeEvent(QResizeEvent *event) override; void resizeEvent(QResizeEvent *event) override;
@@ -68,6 +82,8 @@ private:
void setupUI(); void setupUI();
void refreshViews(); void refreshViews();
void updateViewMode(); void updateViewMode();
void updateActionBar();
QVector<int> getSelectedMailIds() const;
QTreeView *m_treeView; QTreeView *m_treeView;
QListView *m_listView; QListView *m_listView;
@@ -81,9 +97,13 @@ private:
QCheckBox *m_flaggedOnlyCheck; QCheckBox *m_flaggedOnlyCheck;
QCheckBox *m_hasAttachmentsCheck; QCheckBox *m_hasAttachmentsCheck;
QCheckBox *m_pinnedOnlyCheck; QCheckBox *m_pinnedOnlyCheck;
QCheckBox *m_selectAllCheck; // Select all checkbox in action bar
QWidget *m_actionBar; // Action bar widget
QComboBox *m_groupByCombo; QComboBox *m_groupByCombo;
QComboBox *m_displayModeCombo; QComboBox *m_displayModeCombo;
CompactMailDelegate *m_compactDelegate = nullptr; CompactMailDelegate *m_compactDelegate = nullptr;
bool m_compactMode = false; bool m_compactMode = false;
int m_compactThreshold = 650; int m_compactThreshold = 650;
bool m_multiSelectMode = false;
QVector<int> m_selectedMailIds;
}; };