Move TextLabel into its own file

This commit is contained in:
Konstantinos Sideris 2018-09-26 15:17:14 +03:00
parent 9bc7b6305e
commit c64a1bf759
6 changed files with 143 additions and 111 deletions

View file

@ -196,6 +196,7 @@ set(SRC_FILES
src/ui/RippleOverlay.cpp src/ui/RippleOverlay.cpp
src/ui/OverlayWidget.cpp src/ui/OverlayWidget.cpp
src/ui/TextField.cpp src/ui/TextField.cpp
src/ui/TextLabel.cpp
src/ui/ToggleButton.cpp src/ui/ToggleButton.cpp
src/ui/Theme.cpp src/ui/Theme.cpp
src/ui/ThemeManager.cpp src/ui/ThemeManager.cpp
@ -323,6 +324,7 @@ qt5_wrap_cpp(MOC_HEADERS
src/ui/Ripple.h src/ui/Ripple.h
src/ui/RippleOverlay.h src/ui/RippleOverlay.h
src/ui/TextField.h src/ui/TextField.h
src/ui/TextLabel.h
src/ui/ToggleButton.h src/ui/ToggleButton.h
src/ui/Theme.h src/ui/Theme.h
src/ui/ThemeManager.h src/ui/ThemeManager.h

View file

@ -22,11 +22,11 @@
#include "MainWindow.h" #include "MainWindow.h"
#include "TopRoomBar.h" #include "TopRoomBar.h"
#include "Utils.h" #include "Utils.h"
#include "timeline/TimelineItem.h"
#include "ui/Avatar.h" #include "ui/Avatar.h"
#include "ui/FlatButton.h" #include "ui/FlatButton.h"
#include "ui/Menu.h" #include "ui/Menu.h"
#include "ui/OverlayModal.h" #include "ui/OverlayModal.h"
#include "ui/TextLabel.h"
TopRoomBar::TopRoomBar(QWidget *parent) TopRoomBar::TopRoomBar(QWidget *parent)
: QWidget(parent) : QWidget(parent)

View file

@ -28,6 +28,7 @@
#include "Olm.h" #include "Olm.h"
#include "ui/Avatar.h" #include "ui/Avatar.h"
#include "ui/Painter.h" #include "ui/Painter.h"
#include "ui/TextLabel.h"
#include "timeline/TimelineItem.h" #include "timeline/TimelineItem.h"
#include "timeline/widgets/AudioItem.h" #include "timeline/widgets/AudioItem.h"
@ -41,86 +42,6 @@
constexpr int MSG_RIGHT_MARGIN = 7; constexpr int MSG_RIGHT_MARGIN = 7;
constexpr int MSG_PADDING = 20; 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<User>(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) StatusIndicator::StatusIndicator(QWidget *parent)
: QWidget(parent) : QWidget(parent)
{ {
@ -680,6 +601,11 @@ TimelineItem::generateBody(const QString &body)
body_ = new TextLabel(replaceEmoji(body), this); body_ = new TextLabel(replaceEmoji(body), this);
body_->setFont(font_); body_->setFont(font_);
body_->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextBrowserInteraction); 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. // The username/timestamp is displayed along with the message body.

View file

@ -17,7 +17,6 @@
#pragma once #pragma once
#include <QAbstractTextDocumentLayout>
#include <QApplication> #include <QApplication>
#include <QDateTime> #include <QDateTime>
#include <QHBoxLayout> #include <QHBoxLayout>
@ -25,9 +24,6 @@
#include <QLayout> #include <QLayout>
#include <QPainter> #include <QPainter>
#include <QSettings> #include <QSettings>
#include <QStyle>
#include <QStyleOption>
#include <QTextBrowser>
#include <QTimer> #include <QTimer>
#include "AvatarProvider.h" #include "AvatarProvider.h"
@ -43,6 +39,7 @@ class AudioItem;
class VideoItem; class VideoItem;
class FileItem; class FileItem;
class Avatar; class Avatar;
class TextLabel;
enum class StatusIndicatorState enum class StatusIndicatorState
{ {
@ -96,32 +93,6 @@ signals:
void eventRetrieved(const nlohmann::json &); 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 class UserProfileFilter : public QObject
{ {
Q_OBJECT Q_OBJECT

95
src/ui/TextLabel.cpp Normal file
View file

@ -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());
}

38
src/ui/TextLabel.h Normal file
View file

@ -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_;
};