1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
/*
* qtmaildir - a Qt6 mail client for notmuch-indexed Maildirs
* Copyright (C) 2026 Danilo M. <danix@danix.xyz>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "pendingchangesdialog.h"
#include <QDialogButtonBox>
#include <QGridLayout>
#include <QLabel>
#include <QScrollArea>
#include <QVBoxLayout>
QVector<PendingChangeRow> PendingChangesDialog::rowsFor(
const QVector<PendingChange> &changes)
{
QVector<PendingChangeRow> rows;
rows.reserve(changes.size());
// A run is a stretch of changes sharing one id, which the snapshot has
// already grouped. Only the first row of a run carries a subject, so the
// actions read as belonging to the message above them.
//
// Compared against the PREVIOUS id rather than collected into a map: the
// snapshot's order is deliberate (the actions under one message keep the
// order they were made in), and a map would discard it.
QString previousId;
bool first = true;
for (const PendingChange &change : changes) {
const bool startsMessage = first || change.id != previousId;
rows.append(PendingChangeRow{
startsMessage ? change.subject : QString(),
change.action,
startsMessage,
startsMessage ? change.messageCount : -1 });
previousId = change.id;
first = false;
}
return rows;
}
PendingChangesDialog::PendingChangesDialog(
const QVector<PendingChange> &changes, QWidget *parent)
: QDialog(parent), m_rows(rowsFor(changes))
{
setWindowTitle(tr("Unsynced changes"));
auto *layout = new QVBoxLayout(this);
auto *intro = new QLabel(
tr("Changes made here that a sync has not yet carried to the mail "
"store. This list is a snapshot taken when it was opened."),
this);
intro->setWordWrap(true);
layout->addWidget(intro);
auto *content = new QWidget;
auto *grid = new QGridLayout(content);
grid->setColumnStretch(0, 1);
int line = 0;
for (const PendingChangeRow &row : m_rows) {
if (row.startsMessage) {
// PlainText stated rather than left to Qt, for the reason
// MessageDetailsDialog states it on every value: a subject comes
// from a stranger, and a QLabel guesses under Qt::AutoText. Plain
// text cannot interpret markup, so there is nothing to escape.
QString text = row.subject;
if (text.isEmpty()) {
// The id no longer resolves. The row stays, because the count
// the user clicked has to equal the list they are shown.
text = tr("(no longer in the index)");
}
if (row.messageCount >= 0) {
text = tr("%1 (whole thread, %n message(s))", "",
row.messageCount).arg(text);
}
auto *subject = new QLabel(text, content);
subject->setTextFormat(Qt::PlainText);
subject->setWordWrap(true);
grid->addWidget(subject, line, 0);
}
auto *action = new QLabel(row.action, content);
action->setTextFormat(Qt::PlainText);
grid->addWidget(action, line, 1, Qt::AlignTop | Qt::AlignRight);
++line;
}
if (m_rows.isEmpty()) {
grid->addWidget(new QLabel(tr("Nothing is waiting to be synced."),
content),
0, 0);
}
grid->setRowStretch(line, 1);
auto *scroll = new QScrollArea(this);
scroll->setWidget(content);
scroll->setWidgetResizable(true);
layout->addWidget(scroll);
auto *buttons = new QDialogButtonBox(QDialogButtonBox::Close, this);
connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
layout->addWidget(buttons);
resize(600, 380);
}
|