summary refs log tree commit diff
path: root/src/ui
diff options
context:
space:
mode:
authorKonstantinos Sideris <sideris.konstantin@gmail.com>2018-09-26 15:17:14 +0300
committerKonstantinos Sideris <sideris.konstantin@gmail.com>2018-09-26 15:17:14 +0300
commitc64a1bf7592cac57032080c36e4514d4de2a8a95 (patch)
tree529d3f77c1d1639776b2cf47a3e06d33a04d0b64 /src/ui
parentLint (diff)
downloadnheko-c64a1bf7592cac57032080c36e4514d4de2a8a95.tar.xz
Move TextLabel into its own file
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/TextLabel.cpp95
-rw-r--r--src/ui/TextLabel.h38
2 files changed, 133 insertions, 0 deletions
diff --git a/src/ui/TextLabel.cpp b/src/ui/TextLabel.cpp
new file mode 100644
index 00000000..85267674
--- /dev/null
+++ b/src/ui/TextLabel.cpp
@@ -0,0 +1,95 @@
+#include "ui/TextLabel.h"
+
+#include <QAbstractTextDocumentLayout>
+#include <QDesktopServices>
+#include <QEvent>
+#include <QWheelEvent>
+
+#include "Utils.h"
+
+TextLabel::TextLabel(QWidget *parent)
+  : TextLabel(QString(), parent)
+{}
+
+TextLabel::TextLabel(const QString &text, QWidget *parent)
+  : QTextBrowser(parent)
+{
+        document()->setDefaultStyleSheet(QString("a {color: %1; }").arg(utils::linkColor()));
+
+        setText(text);
+        setOpenExternalLinks(true);
+
+        // Make it look and feel like an ordinary label.
+        setReadOnly(true);
+        setFrameStyle(QFrame::NoFrame);
+        QPalette pal = palette();
+        pal.setColor(QPalette::Base, Qt::transparent);
+        setPalette(pal);
+
+        // Wrap anywhere but prefer words, adjust minimum height on the fly.
+        setLineWrapMode(QTextEdit::WidgetWidth);
+        setWordWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
+        connect(document()->documentLayout(),
+                &QAbstractTextDocumentLayout::documentSizeChanged,
+                this,
+                &TextLabel::adjustHeight);
+        document()->setDocumentMargin(0);
+
+        setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+        setFixedHeight(0);
+
+        connect(this, &TextLabel::linkActivated, this, &TextLabel::handleLinkActivation);
+}
+
+void
+TextLabel::focusOutEvent(QFocusEvent *e)
+{
+        QTextBrowser::focusOutEvent(e);
+
+        QTextCursor cursor = textCursor();
+        cursor.clearSelection();
+        setTextCursor(cursor);
+}
+
+void
+TextLabel::mousePressEvent(QMouseEvent *e)
+{
+        link_ = (e->button() & Qt::LeftButton) ? anchorAt(e->pos()) : QString();
+        QTextBrowser::mousePressEvent(e);
+}
+
+void
+TextLabel::mouseReleaseEvent(QMouseEvent *e)
+{
+        if (e->button() & Qt::LeftButton && !link_.isEmpty() && anchorAt(e->pos()) == link_) {
+                emit linkActivated(link_);
+                return;
+        }
+
+        QTextBrowser::mouseReleaseEvent(e);
+}
+
+void
+TextLabel::wheelEvent(QWheelEvent *event)
+{
+        event->ignore();
+}
+
+void
+TextLabel::handleLinkActivation(const QUrl &url)
+{
+        auto parts          = url.toString().split('/');
+        auto defaultHandler = [](const QUrl &url) { QDesktopServices::openUrl(url); };
+
+        if (url.host() != "matrix.to" || parts.isEmpty())
+                return defaultHandler(url);
+
+        try {
+                using namespace mtx::identifiers;
+                parse<User>(parts.last().toStdString());
+        } catch (const std::exception &) {
+                return defaultHandler(url);
+        }
+
+        emit userProfileTriggered(parts.last());
+}
diff --git a/src/ui/TextLabel.h b/src/ui/TextLabel.h
new file mode 100644
index 00000000..da6e9c4b
--- /dev/null
+++ b/src/ui/TextLabel.h
@@ -0,0 +1,38 @@
+#pragma once
+
+#include <QSize>
+#include <QString>
+#include <QTextBrowser>
+#include <QUrl>
+
+class QMouseEvent;
+class QFocusEvent;
+class QWheelEvent;
+
+class TextLabel : public QTextBrowser
+{
+        Q_OBJECT
+
+public:
+        TextLabel(const QString &text, QWidget *parent = nullptr);
+        TextLabel(QWidget *parent = nullptr);
+
+        void wheelEvent(QWheelEvent *event) override;
+        void clearLinks() { link_.clear(); }
+
+protected:
+        void mousePressEvent(QMouseEvent *e) override;
+        void mouseReleaseEvent(QMouseEvent *e) override;
+        void focusOutEvent(QFocusEvent *e) override;
+
+private slots:
+        void adjustHeight(const QSizeF &size) { setFixedHeight(size.height()); }
+        void handleLinkActivation(const QUrl &link);
+
+signals:
+        void userProfileTriggered(const QString &user_id);
+        void linkActivated(const QUrl &link);
+
+private:
+        QString link_;
+};