1 /* Copyright (C) 2006 - 2015 Jan Kundrát <jkt@kde.org>
3 This file is part of the Trojita Qt IMAP e-mail client,
4 http://trojita.flaska.net/
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 2 of
9 the License or (at your option) version 3 or any later version
10 accepted by the membership of KDE e.V. (or its successor approved
11 by the membership of KDE e.V.), which shall act as a proxy
12 defined in Section 14 of version 3 of the license.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "Gui/AddressRowWidget.h"
23 #include "Gui/FlowLayout.h"
24 #include "Gui/OneEnvelopeAddress.h"
27 #include <QMouseEvent>
29 #include <QTextDocument>
33 static const int nonExpandingLength
= 3*33;
35 static int plainChars(const QLabel
*l
)
37 static QTextDocument converter
;
38 converter
.setHtml(l
->text());
39 return converter
.toPlainText().length();
42 AddressRowWidget::AddressRowWidget(QWidget
*parent
, const QString
&description
,
43 const QList
<Imap::Message::MailAddress
> &addresses
, MessageView
*messageView
):
44 QWidget(parent
), m_expander(0), m_expandedLength(0)
46 FlowLayout
*lay
= new FlowLayout(this, 0, 0, 0);
49 setSizePolicy(QSizePolicy::Expanding
, QSizePolicy::Preferred
);
51 addAddresses(description
, addresses
, messageView
);
54 void AddressRowWidget::addAddresses(const QString
&description
, const QList
<Imap::Message::MailAddress
> &addresses
, MessageView
*messageView
)
57 layout()->removeWidget(m_expander
);
58 if (!description
.isEmpty()) {
59 QLabel
*title
= new QLabel(description
, this);
60 title
->setSizePolicy(QSizePolicy::Fixed
, QSizePolicy::Fixed
);
61 title
->setTextInteractionFlags(Qt::TextSelectableByMouse
| Qt::LinksAccessibleByMouse
);
62 layout()->addWidget(title
);
66 int collapse
= m_expander
? m_expander
->expanding() : 0;
67 for (int i
= 0; i
< addresses
.size(); ++i
) {
68 auto *w
= new OneEnvelopeAddress(this, addresses
[i
], messageView
,
69 i
== addresses
.size() - 1 ?
70 OneEnvelopeAddress::Position::Last
:
71 OneEnvelopeAddress::Position::Middle
);
72 m_expandedLength
+= plainChars(w
);
73 layout()->addWidget(w
);
74 if (collapse
|| (i
> 1 && m_expandedLength
> nonExpandingLength
)) {
79 if (collapse
&& !m_expander
) {
80 m_expander
= new Expander(this, collapse
);
81 connect(m_expander
, &Expander::clicked
, this, &AddressRowWidget::toggle
);
84 layout()->addWidget(m_expander
);
87 void AddressRowWidget::toggle()
90 if (m_expander
->expanding()) {
91 m_expander
->setExpanding(false);
92 for (int i
= 0; i
< layout()->count(); ++i
) {
93 if (QWidget
*w
= layout()->itemAt(i
)->widget())
97 int chars
= 0, addresses
= 0;
99 for (int i
= 0; i
< layout()->count(); ++i
) {
100 QWidget
*w
= layout()->itemAt(i
)->widget();
101 if (collapse
&& w
!= m_expander
) {
106 if (OneEnvelopeAddress
*oea
= qobject_cast
<OneEnvelopeAddress
*>(w
)) {
108 chars
+= plainChars(oea
);
109 if ((collapse
= (addresses
> 1 && chars
> nonExpandingLength
)))
113 m_expander
->setExpanding(collapse
);
117 Expander::Expander(QWidget
*parent
, int count
) : QLabel(parent
)
119 setCursor(Qt::PointingHandCursor
);
123 int Expander::expanding() const {
127 void Expander::setExpanding(const int expanding
)
129 m_expanding
= expanding
;
130 setToolTip(expanding
? tr("Click to see %1 more items").arg(expanding
) : tr("Click to collapse"));
133 QSize
Expander::sizeHint() const
135 QSize s
= QLabel::sizeHint();
136 s
.setWidth(m_expanding
? 2*s
.height() : s
.height());
140 void Expander::mouseReleaseEvent(QMouseEvent
*me
)
142 if (me
->button() == Qt::LeftButton
)
146 void Expander::paintEvent(QPaintEvent
*pe
)
149 p
.setRenderHint(QPainter::Antialiasing
);
151 r
.setWidth(height());
154 p
.setPen(palette().color(foregroundRole()));
155 p
.setBrush(Qt::NoBrush
);
156 p
.drawText(r
, Qt::AlignCenter
, QStringLiteral("\u2026"));
157 r
.moveRight(rect().right());
159 p
.setBrush(palette().color(foregroundRole()));
162 p
.setBrush(palette().color(backgroundRole()));
163 float d
= r
.height()/4.0f
;
165 // the unicode triangles are not necessarily centered - looks crap
167 r
.translate(r
.width()/8.0f
,0); // fix gravity
168 const QPointF points
[3] = { r
.topLeft(), r
.bottomLeft(), QPointF(r
.right(), r
.y() + r
.height()/2.0) };
169 p
.drawConvexPolygon(points
, 3);
171 r
.translate(-r
.width()/8.0f
,0); // fix gravity
172 const QPointF points
[3] = { r
.topRight(), r
.bottomRight(), QPointF(r
.left(), r
.y() + r
.height()/2.0) };
173 p
.drawConvexPolygon(points
, 3);