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:
2026-04-14 10:51:06 +01:00
parent 51f3c21121
commit cf12defd28
15214 changed files with 20594243 additions and 269 deletions
@@ -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"