From c64a1bf7592cac57032080c36e4514d4de2a8a95 Mon Sep 17 00:00:00 2001 From: Konstantinos Sideris Date: Wed, 26 Sep 2018 15:17:14 +0300 Subject: [PATCH] Move TextLabel into its own file --- CMakeLists.txt | 2 + src/TopRoomBar.cpp | 2 +- src/timeline/TimelineItem.cpp | 86 +++---------------------------- src/timeline/TimelineItem.h | 31 +----------- src/ui/TextLabel.cpp | 95 +++++++++++++++++++++++++++++++++++ src/ui/TextLabel.h | 38 ++++++++++++++ 6 files changed, 143 insertions(+), 111 deletions(-) create mode 100644 src/ui/TextLabel.cpp create mode 100644 src/ui/TextLabel.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 43fcb977..e5aa8952 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -196,6 +196,7 @@ set(SRC_FILES src/ui/RippleOverlay.cpp src/ui/OverlayWidget.cpp src/ui/TextField.cpp + src/ui/TextLabel.cpp src/ui/ToggleButton.cpp src/ui/Theme.cpp src/ui/ThemeManager.cpp @@ -323,6 +324,7 @@ qt5_wrap_cpp(MOC_HEADERS src/ui/Ripple.h src/ui/RippleOverlay.h src/ui/TextField.h + src/ui/TextLabel.h src/ui/ToggleButton.h src/ui/Theme.h src/ui/ThemeManager.h diff --git a/src/TopRoomBar.cpp b/src/TopRoomBar.cpp index 5fc6ab4a..a5d264c7 100644 --- a/src/TopRoomBar.cpp +++ b/src/TopRoomBar.cpp @@ -22,11 +22,11 @@ #include "MainWindow.h" #include "TopRoomBar.h" #include "Utils.h" -#include "timeline/TimelineItem.h" #include "ui/Avatar.h" #include "ui/FlatButton.h" #include "ui/Menu.h" #include "ui/OverlayModal.h" +#include "ui/TextLabel.h" TopRoomBar::TopRoomBar(QWidget *parent) : QWidget(parent) diff --git a/src/timeline/TimelineItem.cpp b/src/timeline/TimelineItem.cpp index b62437cd..9558c397 100644 --- a/src/timeline/TimelineItem.cpp +++ b/src/timeline/TimelineItem.cpp @@ -28,6 +28,7 @@ #include "Olm.h" #include "ui/Avatar.h" #include "ui/Painter.h" +#include "ui/TextLabel.h" #include "timeline/TimelineItem.h" #include "timeline/widgets/AudioItem.h" @@ -41,86 +42,6 @@ constexpr int MSG_RIGHT_MARGIN = 7; constexpr int MSG_PADDING = 20; -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, [](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(parts.last().toStdString()); - } catch (const std::exception &) { - return defaultHandler(url); - } - - auto user_id = parts.last(); - auto room_id = ChatPage::instance()->currentRoom(); - - MainWindow::instance()->openUserProfile(user_id, room_id); - }); -} - -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); -} - StatusIndicator::StatusIndicator(QWidget *parent) : QWidget(parent) { @@ -680,6 +601,11 @@ TimelineItem::generateBody(const QString &body) body_ = new TextLabel(replaceEmoji(body), this); body_->setFont(font_); body_->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextBrowserInteraction); + + connect(body_, &TextLabel::userProfileTriggered, this, [](const QString &user_id) { + MainWindow::instance()->openUserProfile(user_id, + ChatPage::instance()->currentRoom()); + }); } // The username/timestamp is displayed along with the message body. diff --git a/src/timeline/TimelineItem.h b/src/timeline/TimelineItem.h index b2e6c8b5..ae486257 100644 --- a/src/timeline/TimelineItem.h +++ b/src/timeline/TimelineItem.h @@ -17,7 +17,6 @@ #pragma once -#include #include #include #include @@ -25,9 +24,6 @@ #include #include #include -#include -#include -#include #include #include "AvatarProvider.h" @@ -43,6 +39,7 @@ class AudioItem; class VideoItem; class FileItem; class Avatar; +class TextLabel; enum class StatusIndicatorState { @@ -96,32 +93,6 @@ signals: void eventRetrieved(const nlohmann::json &); }; -class TextLabel : public QTextBrowser -{ - Q_OBJECT - -public: - TextLabel(const QString &text, QWidget *parent = nullptr); - TextLabel(QWidget *parent = nullptr); - - void wheelEvent(QWheelEvent *event) override { event->ignore(); } - 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()); } - -signals: - void linkActivated(const QUrl &link); - -private: - QString link_; -}; - class UserProfileFilter : public QObject { Q_OBJECT 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 +#include +#include +#include + +#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(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 +#include +#include +#include + +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_; +};