File indexing completed on 2024-12-01 04:37:01

0001 /*
0002    SPDX-FileCopyrightText: 2021-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "roomheaderlabel.h"
0008 
0009 #include <KLocalizedString>
0010 #include <QDesktopServices>
0011 #include <QTextDocument>
0012 
0013 RoomHeaderLabel::RoomHeaderLabel(QWidget *parent)
0014     : QLabel(parent)
0015 {
0016     setWordWrap(true);
0017     setTextInteractionFlags(Qt::TextBrowserInteraction);
0018     setTextFormat(Qt::RichText);
0019     setVisible(false);
0020     connect(this, &QLabel::linkActivated, this, &RoomHeaderLabel::slotMoreInfo);
0021 }
0022 
0023 RoomHeaderLabel::~RoomHeaderLabel() = default;
0024 
0025 void RoomHeaderLabel::resizeEvent(QResizeEvent *ev)
0026 {
0027     QLabel::resizeEvent(ev);
0028     updateSqueezedText();
0029 }
0030 
0031 void RoomHeaderLabel::updateSqueezedText()
0032 {
0033     setToolTip(QString());
0034 
0035     if (mFullText.isEmpty()) {
0036         QLabel::setText(QString());
0037         setVisible(false);
0038         return;
0039     }
0040     setVisible(true);
0041     const QString text = rPixelSqueeze(mFullText, width() - 10);
0042     QLabel::setText(QLatin1String("<qt>") + text + QLatin1String("</qt>"));
0043     if (mFullText != text && !mExpandTopic) {
0044         setToolTip(mFullText);
0045     }
0046 }
0047 
0048 void RoomHeaderLabel::slotMoreInfo(const QString &content)
0049 {
0050     if (content == QLatin1String("showmoretext")) {
0051         mExpandTopic = true;
0052         updateSqueezedText();
0053     } else if (content == QLatin1String("showlesstext")) {
0054         mExpandTopic = false;
0055         updateSqueezedText();
0056     } else {
0057         QDesktopServices::openUrl(QUrl(content));
0058     }
0059 }
0060 
0061 QString RoomHeaderLabel::rPixelSqueeze(const QString &text, int maxPixels) const
0062 {
0063     const auto tSize = textSize(text);
0064     int tHeight = tSize.height();
0065     int tw = tSize.width();
0066     QString tmp = text;
0067     const QString showMoreText = i18n("(Show More Info...)");
0068     if (tHeight > (3 * fontMetrics().ascent() + fontMetrics().descent())) {
0069         if (!mExpandTopic) {
0070             if (tw > maxPixels) {
0071                 int em = fontMetrics().maxWidth();
0072                 maxPixels -= fontMetrics().horizontalAdvance(showMoreText);
0073 
0074                 // On some MacOS system, maxWidth may return 0
0075                 if (em == 0) {
0076                     for (QChar c : text) {
0077                         em = qMax(em, fontMetrics().horizontalAdvance(c));
0078                     }
0079                 }
0080                 while ((tw > maxPixels) && !tmp.isEmpty()) {
0081                     const int len = tmp.length();
0082                     int delta = (em == 0) ? 0 : (tw - maxPixels) / em;
0083                     delta = qBound(1, delta, len);
0084 
0085                     tmp.remove(len - delta, delta);
0086                     tw = textSize(tmp).width();
0087                 }
0088             } else {
0089                 tmp = tmp.split(QStringLiteral("\n")).at(0);
0090             }
0091             if (!tmp.endsWith(QLatin1Char('\n'))) {
0092                 tmp.append(QLatin1Char('\n'));
0093             }
0094             return tmp.append(QStringLiteral("<a href=\"showmoretext\"> %1</a>").arg(showMoreText));
0095         } else {
0096             if (!tmp.endsWith(QLatin1Char('\n'))) {
0097                 tmp.append(QLatin1Char('\n'));
0098             }
0099             return tmp.append(QStringLiteral("<a href=\"showlesstext\"> %1</a>").arg(i18n("(Show Less Info...)")));
0100         }
0101     }
0102     return text;
0103 }
0104 
0105 QSize RoomHeaderLabel::textSize(const QString &text) const
0106 {
0107     QTextDocument document;
0108     document.setDefaultFont(font());
0109     document.setHtml(QLatin1String("<qt>") + text + QLatin1String("</qt>"));
0110 
0111     return document.size().toSize();
0112 }
0113 
0114 const QString &RoomHeaderLabel::fullText() const
0115 {
0116     return mFullText;
0117 }
0118 
0119 void RoomHeaderLabel::setRoomAnnouncement(const QString &announcement)
0120 {
0121     mAnnouncement = announcement;
0122     updateHeaderText();
0123 }
0124 
0125 void RoomHeaderLabel::setRoomTopic(const QString &topic)
0126 {
0127     mTopic = topic;
0128     updateHeaderText();
0129 }
0130 
0131 void RoomHeaderLabel::updateHeaderText()
0132 {
0133     mFullText.clear();
0134     if (!mTopic.isEmpty()) {
0135         mFullText = mTopic;
0136     }
0137     if (!mAnnouncement.isEmpty()) {
0138         if (!mFullText.isEmpty()) {
0139             mFullText += QLatin1Char('\n');
0140         }
0141         mFullText += mAnnouncement;
0142     }
0143     updateSqueezedText();
0144 }
0145 
0146 #include "moc_roomheaderlabel.cpp"