Advance Wayland and KDE package bring-up
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -0,0 +1,254 @@
|
||||
/*
|
||||
This file is part of the KDE libraries
|
||||
SPDX-FileCopyrightText: 2000 Ronny Standtke <Ronny.Standtke@gmx.de>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-only
|
||||
*/
|
||||
|
||||
#include "ksqueezedtextlabel.h"
|
||||
#include <QAction>
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QContextMenuEvent>
|
||||
#include <QMenu>
|
||||
#include <QRegularExpression>
|
||||
#include <QScreen>
|
||||
#include <QTextDocument>
|
||||
|
||||
class KSqueezedTextLabelPrivate
|
||||
{
|
||||
public:
|
||||
void copyFullText()
|
||||
{
|
||||
QApplication::clipboard()->setText(fullText);
|
||||
}
|
||||
|
||||
QString fullText;
|
||||
Qt::TextElideMode elideMode;
|
||||
};
|
||||
|
||||
KSqueezedTextLabel::KSqueezedTextLabel(const QString &text, QWidget *parent)
|
||||
: QLabel(parent)
|
||||
, d(new KSqueezedTextLabelPrivate)
|
||||
{
|
||||
setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
|
||||
d->fullText = text;
|
||||
d->elideMode = Qt::ElideMiddle;
|
||||
squeezeTextToLabel();
|
||||
}
|
||||
|
||||
KSqueezedTextLabel::KSqueezedTextLabel(QWidget *parent)
|
||||
: QLabel(parent)
|
||||
, d(new KSqueezedTextLabelPrivate)
|
||||
{
|
||||
setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
|
||||
d->elideMode = Qt::ElideMiddle;
|
||||
}
|
||||
|
||||
KSqueezedTextLabel::~KSqueezedTextLabel() = default;
|
||||
|
||||
void KSqueezedTextLabel::resizeEvent(QResizeEvent *)
|
||||
{
|
||||
squeezeTextToLabel();
|
||||
}
|
||||
|
||||
QSize KSqueezedTextLabel::minimumSizeHint() const
|
||||
{
|
||||
QSize sh = QLabel::minimumSizeHint();
|
||||
sh.setWidth(-1);
|
||||
return sh;
|
||||
}
|
||||
|
||||
QSize KSqueezedTextLabel::sizeHint() const
|
||||
{
|
||||
if (!isSqueezed()) {
|
||||
return QLabel::sizeHint();
|
||||
}
|
||||
int maxWidth = screen()->geometry().width() * 3 / 4;
|
||||
QFontMetrics fm(fontMetrics());
|
||||
// Do exactly like qlabel.cpp to avoid slight differences in results
|
||||
// (see https://invent.kde.org/frameworks/kwidgetsaddons/-/merge_requests/100)
|
||||
int textWidth = fm.boundingRect(0, 0, 2000, 2000, Qt::AlignAbsolute | Qt::TextExpandTabs | Qt::AlignLeft, d->fullText).width();
|
||||
if (textWidth > maxWidth) {
|
||||
textWidth = maxWidth;
|
||||
}
|
||||
const int chromeWidth = width() - contentsRect().width();
|
||||
return QSize(textWidth + chromeWidth, QLabel::sizeHint().height());
|
||||
}
|
||||
|
||||
void KSqueezedTextLabel::setIndent(int indent)
|
||||
{
|
||||
QLabel::setIndent(indent);
|
||||
squeezeTextToLabel();
|
||||
}
|
||||
|
||||
void KSqueezedTextLabel::setMargin(int margin)
|
||||
{
|
||||
QLabel::setMargin(margin);
|
||||
squeezeTextToLabel();
|
||||
}
|
||||
|
||||
void KSqueezedTextLabel::setText(const QString &text)
|
||||
{
|
||||
d->fullText = text;
|
||||
squeezeTextToLabel();
|
||||
}
|
||||
|
||||
void KSqueezedTextLabel::clear()
|
||||
{
|
||||
d->fullText.clear();
|
||||
QLabel::clear();
|
||||
}
|
||||
|
||||
void KSqueezedTextLabel::squeezeTextToLabel()
|
||||
{
|
||||
QFontMetrics fm(fontMetrics());
|
||||
const int labelWidth = contentsRect().width();
|
||||
QStringList squeezedLines;
|
||||
bool squeezed = false;
|
||||
const auto textLines = d->fullText.split(QLatin1Char('\n'));
|
||||
squeezedLines.reserve(textLines.size());
|
||||
for (const QString &line : textLines) {
|
||||
int lineWidth = fm.boundingRect(line).width();
|
||||
if (lineWidth > labelWidth) {
|
||||
squeezed = true;
|
||||
squeezedLines << fm.elidedText(line, d->elideMode, labelWidth);
|
||||
} else {
|
||||
squeezedLines << line;
|
||||
}
|
||||
}
|
||||
|
||||
if (squeezed) {
|
||||
QLabel::setText(squeezedLines.join(QLatin1Char('\n')));
|
||||
setToolTip(d->fullText);
|
||||
} else {
|
||||
QLabel::setText(d->fullText);
|
||||
setToolTip(QString());
|
||||
}
|
||||
}
|
||||
|
||||
QRect KSqueezedTextLabel::contentsRect() const
|
||||
{
|
||||
// calculation according to API docs for QLabel::indent
|
||||
const int margin = this->margin();
|
||||
int indent = this->indent();
|
||||
if (indent < 0) {
|
||||
if (frameWidth() == 0) {
|
||||
indent = 0;
|
||||
} else {
|
||||
indent = fontMetrics().horizontalAdvance(QLatin1Char('x')) / 2 - margin;
|
||||
}
|
||||
}
|
||||
|
||||
QRect result = QLabel::contentsRect();
|
||||
if (indent > 0) {
|
||||
const int alignment = this->alignment();
|
||||
if (alignment & Qt::AlignLeft) {
|
||||
result.setLeft(result.left() + indent);
|
||||
}
|
||||
if (alignment & Qt::AlignTop) {
|
||||
result.setTop(result.top() + indent);
|
||||
}
|
||||
if (alignment & Qt::AlignRight) {
|
||||
result.setRight(result.right() - indent);
|
||||
}
|
||||
if (alignment & Qt::AlignBottom) {
|
||||
result.setBottom(result.bottom() - indent);
|
||||
}
|
||||
}
|
||||
|
||||
result.adjust(margin, margin, -margin, -margin);
|
||||
return result;
|
||||
}
|
||||
|
||||
void KSqueezedTextLabel::setAlignment(Qt::Alignment alignment)
|
||||
{
|
||||
// save fullText and restore it
|
||||
QString tmpFull(d->fullText);
|
||||
QLabel::setAlignment(alignment);
|
||||
d->fullText = tmpFull;
|
||||
}
|
||||
|
||||
Qt::TextElideMode KSqueezedTextLabel::textElideMode() const
|
||||
{
|
||||
return d->elideMode;
|
||||
}
|
||||
|
||||
void KSqueezedTextLabel::setTextElideMode(Qt::TextElideMode mode)
|
||||
{
|
||||
d->elideMode = mode;
|
||||
squeezeTextToLabel();
|
||||
}
|
||||
|
||||
QString KSqueezedTextLabel::fullText() const
|
||||
{
|
||||
return d->fullText;
|
||||
}
|
||||
|
||||
bool KSqueezedTextLabel::isSqueezed() const
|
||||
{
|
||||
return d->fullText != text();
|
||||
}
|
||||
|
||||
void KSqueezedTextLabel::contextMenuEvent(QContextMenuEvent *ev)
|
||||
{
|
||||
// We want to reimplement "Copy" to include the elided text.
|
||||
// But this means reimplementing the full popup menu, so no more
|
||||
// copy-link-address or copy-selection support anymore, since we
|
||||
// have no access to the QTextDocument.
|
||||
// Maybe we should have a boolean flag in KSqueezedTextLabel itself for
|
||||
// whether to show the "Copy Full Text" custom popup?
|
||||
// For now I chose to show it when the text is squeezed; when it's not, the
|
||||
// standard popup menu can do the job (select all, copy).
|
||||
|
||||
if (isSqueezed()) {
|
||||
QMenu menu(this);
|
||||
|
||||
QAction *act = new QAction(QIcon::fromTheme(QStringLiteral("edit-copy")), tr("&Copy Full Text", "@action:inmenu"), &menu);
|
||||
connect(act, &QAction::triggered, this, [this]() {
|
||||
d->copyFullText();
|
||||
});
|
||||
menu.addAction(act);
|
||||
|
||||
ev->accept();
|
||||
menu.exec(ev->globalPos());
|
||||
} else {
|
||||
QLabel::contextMenuEvent(ev);
|
||||
}
|
||||
}
|
||||
|
||||
void KSqueezedTextLabel::mouseReleaseEvent(QMouseEvent *ev)
|
||||
{
|
||||
if (QApplication::clipboard()->supportsSelection() //
|
||||
&& textInteractionFlags() != Qt::NoTextInteraction //
|
||||
&& ev->button() == Qt::LeftButton //
|
||||
&& !d->fullText.isEmpty() //
|
||||
&& hasSelectedText()) {
|
||||
// Expand "..." when selecting with the mouse
|
||||
QString txt = selectedText();
|
||||
const QChar ellipsisChar(0x2026); // from qtextengine.cpp
|
||||
const int dotsPos = txt.indexOf(ellipsisChar);
|
||||
if (dotsPos > -1) {
|
||||
// Ex: abcde...yz, selecting de...y (selectionStart=3)
|
||||
// charsBeforeSelection = selectionStart = 2 (ab)
|
||||
// charsAfterSelection = 1 (z)
|
||||
// final selection length= 26 - 2 - 1 = 23
|
||||
const int start = selectionStart();
|
||||
int charsAfterSelection = text().length() - start - selectedText().length();
|
||||
txt = d->fullText;
|
||||
// Strip markup tags
|
||||
if (textFormat() == Qt::RichText //
|
||||
|| (textFormat() == Qt::AutoText && Qt::mightBeRichText(txt))) {
|
||||
txt.remove(QRegularExpression(QStringLiteral("<[^>]*>")));
|
||||
// account for stripped characters
|
||||
charsAfterSelection -= d->fullText.length() - txt.length();
|
||||
}
|
||||
txt = txt.mid(selectionStart(), txt.length() - start - charsAfterSelection);
|
||||
}
|
||||
QApplication::clipboard()->setText(txt, QClipboard::Selection);
|
||||
} else {
|
||||
QLabel::mouseReleaseEvent(ev);
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_ksqueezedtextlabel.cpp"
|
||||
Reference in New Issue
Block a user