[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [trojita] src/Gui: make longer address rows expandable
From:       Thomas_Lübking <thomas.luebking () gmail ! com>
Date:       2016-03-05 16:57:04
Message-ID: E1acFVo-0000Mk-Q9 () scm ! kde ! org
[Download RAW message or body]

Git commit 877a06cfc49142e28b54a1052e7eb7303823f444 by Thomas Lübking.
Committed on 28/02/2016 at 12:07.
Pushed by gerrit into branch 'master'.

make longer address rows expandable

Change-Id: I40cb378faca4dfab9cdfa2616a7dd6debea2211a

M  +116  -5    src/Gui/AddressRowWidget.cpp
M  +23   -1    src/Gui/AddressRowWidget.h

http://commits.kde.org/trojita/877a06cfc49142e28b54a1052e7eb7303823f444

diff --git a/src/Gui/AddressRowWidget.cpp b/src/Gui/AddressRowWidget.cpp
index eee7409..aa97d68 100644
--- a/src/Gui/AddressRowWidget.cpp
+++ b/src/Gui/AddressRowWidget.cpp
@@ -23,11 +23,23 @@
 #include "Gui/FlowLayout.h"
 #include "Gui/OneEnvelopeAddress.h"
 
+#include <QLabel>
+#include <QMouseEvent>
+#include <QPainter>
+#include <QTextDocument>
+
 namespace Gui {
 
+static int plainChars(const QLabel *l)
+{
+    static QTextDocument converter;
+    converter.setHtml(l->text());
+    return converter.toPlainText().length();
+}
+
 AddressRowWidget::AddressRowWidget(QWidget *parent, const QString &headerName,
                                    const QList<Imap::Message::MailAddress> \
                &addresses, MessageView *messageView):
-    QWidget(parent)
+    QWidget(parent), m_expander(0)
 {
     FlowLayout *lay = new FlowLayout(this, 0, 0, -1);
     setLayout(lay);
@@ -38,13 +50,112 @@ AddressRowWidget::AddressRowWidget(QWidget *parent, const \
QString &headerName,  title->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
     title->setTextInteractionFlags(Qt::TextSelectableByMouse | \
Qt::LinksAccessibleByMouse);  lay->addWidget(title);
+    int chars = 0;
+    bool collapse = false;
     for (int i = 0; i < addresses.size(); ++i) {
-        QWidget *w = new OneEnvelopeAddress(this, addresses[i], messageView,
-                                            i == addresses.size() - 1 ?
-                                                OneEnvelopeAddress::Position::Last :
-                                                \
OneEnvelopeAddress::Position::Middle); +        auto *w = new \
OneEnvelopeAddress(this, addresses[i], messageView, +                                 \
i == addresses.size() - 1 ? +                                         \
OneEnvelopeAddress::Position::Last : +                                         \
OneEnvelopeAddress::Position::Middle); +        chars += plainChars(w);
         lay->addWidget(w);
+        if (i > 1 && chars > 66) {
+            w->hide();
+            collapse = true;
+        }
+    }
+    if (collapse) {
+        lay->addWidget(m_expander = new Expander(this));
+        connect(m_expander, &Expander::clicked, this, &AddressRowWidget::toggle);
+    }
+}
+
+void AddressRowWidget::toggle()
+{
+    Q_ASSERT(m_expander);
+    if (m_expander->isExpanding()) {
+        m_expander->setExpanding(false);
+        for (int i = 0; i < layout()->count(); ++i) {
+            if (QWidget *w = layout()->itemAt(i)->widget())
+                w->show();
+        }
+    } else {
+        int chars = 0, addresses = 0;
+        int collapse = 0;
+        for (int i = 0; i < layout()->count(); ++i) {
+            if (OneEnvelopeAddress *w =
+                qobject_cast<OneEnvelopeAddress*>(layout()->itemAt(i)->widget())) {
+                ++addresses;
+                chars += plainChars(w);
+                if (addresses > 1 && chars > 66) {
+                    ++collapse;
+                    w->hide();
+                }
+            }
+        }
+        m_expander->setExpanding(collapse);
+    }
+}
+
+Expander::Expander(QWidget *parent, Expander::Direction d) : QLabel(parent)
+{
+    setCursor(Qt::PointingHandCursor);
+    setExpanding(d == Direction::Expanding);
+}
+
+bool Expander::isExpanding() const {
+    return m_expanding;
+}
+
+void Expander::setExpanding(const int expanding)
+{
+    m_expanding = expanding;
+    setToolTip(expanding ? tr("Click to see %1 more items").arg(expanding) : \
tr("Click to collapse")); +}
+
+QSize Expander::sizeHint() const
+{
+    QSize s = QLabel::sizeHint();
+    s.setWidth(m_expanding ? 2*s.height() : s.height());
+    return s;
+}
+
+void Expander::mouseReleaseEvent(QMouseEvent *me)
+{
+    if (me->button() == Qt::LeftButton)
+        emit clicked();
+}
+
+void Expander::paintEvent(QPaintEvent *pe)
+{
+    QPainter p(this);
+    p.setRenderHint(QPainter::Antialiasing);
+    QRectF r(rect());
+    r.setWidth(height());
+    if (m_expanding) {
+        // ellipsis
+        p.setPen(palette().color(foregroundRole()));
+        p.setBrush(Qt::NoBrush);
+        p.drawText(r, Qt::AlignCenter, QStringLiteral("\u2026"));
+        r.moveRight(rect().right());
+    }
+    p.setBrush(palette().color(foregroundRole()));
+    p.setPen(Qt::NoPen);
+    p.drawEllipse(r);
+    p.setBrush(palette().color(backgroundRole()));
+    float d = r.height()/4.0f;
+    r.adjust(d,d,-d,-d);
+    // the unicode triangles are not necessarily centered - looks crap
+    if (m_expanding) {
+        r.translate(r.width()/8.0f,0); // fix gravity
+        const QPointF points[3] = { r.topLeft(), r.bottomLeft(), QPointF(r.right(), \
r.y() + r.height()/2.0) }; +        p.drawConvexPolygon(points, 3);
+    } else {
+        r.translate(-r.width()/8.0f,0); // fix gravity
+        const QPointF points[3] = { r.topRight(), r.bottomRight(), QPointF(r.left(), \
r.y() + r.height()/2.0) }; +        p.drawConvexPolygon(points, 3);
     }
+    p.end();
 }
 
 }
diff --git a/src/Gui/AddressRowWidget.h b/src/Gui/AddressRowWidget.h
index 0e02df9..46fa109 100644
--- a/src/Gui/AddressRowWidget.h
+++ b/src/Gui/AddressRowWidget.h
@@ -22,7 +22,7 @@
 #ifndef GUI_ADDRESSROWWIDGET_H
 #define GUI_ADDRESSROWWIDGET_H
 
-#include <QWidget>
+#include <QLabel>
 
 namespace Imap {
 namespace Message {
@@ -34,6 +34,25 @@ namespace Gui {
 
 class MessageView;
 
+/** @short A label with expansion indicating text and "clicked" signal */
+class Expander : public QLabel
+{
+    Q_OBJECT
+public:
+    enum class Direction { Collapsing = 0, Expanding };
+    explicit Expander(QWidget *parent, Direction d = Direction::Expanding);
+    bool isExpanding() const;
+    void setExpanding(const int expanding);
+    QSize sizeHint() const;
+signals:
+    void clicked();
+protected:
+    void mouseReleaseEvent(QMouseEvent *me);
+    void paintEvent(QPaintEvent *pe);
+private:
+    int m_expanding;
+};
+
 /** @short Widget displaying the message envelope */
 class AddressRowWidget : public QWidget
 {
@@ -41,9 +60,12 @@ class AddressRowWidget : public QWidget
 public:
     AddressRowWidget(QWidget *parent, const QString &headerName, const \
QList<Imap::Message::MailAddress> &addresses, MessageView *messageView);  
+private slots:
+    void toggle();
 private:
     AddressRowWidget(const AddressRowWidget &) = delete;
     AddressRowWidget &operator=(const AddressRowWidget &) = delete;
+    Expander *m_expander;
 };
 
 }


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic