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,66 @@
/* -*- C++ -*-
This file is part of the KDE libraries
SPDX-FileCopyrightText: 1997 Tim D. Gilman <tdgilman@best.org>
SPDX-FileCopyrightText: 1998-2001 Mirko Boehm <mirko@kde.org>
SPDX-FileCopyrightText: 2007 John Layt <john@layt.net>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "kdatevalidator.h"
#include <QDate>
#include <QLocale>
class KDateValidatorPrivate
{
public:
KDateValidatorPrivate(KDateValidator *qq)
: q(qq)
{
}
~KDateValidatorPrivate()
{
}
KDateValidator *const q;
};
KDateValidator::KDateValidator(QObject *parent)
: QValidator(parent)
{
}
KDateValidator::~KDateValidator() = default;
QValidator::State KDateValidator::validate(QString &text, int &unused) const
{
Q_UNUSED(unused);
QDate temp;
// ----- everything is tested in date():
return date(text, temp);
}
QValidator::State KDateValidator::date(const QString &text, QDate &d) const
{
QLocale::FormatType formats[] = {QLocale::LongFormat, QLocale::ShortFormat, QLocale::NarrowFormat};
QLocale locale;
for (int i = 0; i < 3; i++) {
QDate tmp = locale.toDate(text, formats[i]);
if (tmp.isValid()) {
d = tmp;
return Acceptable;
}
}
return QValidator::Intermediate;
}
void KDateValidator::fixup(QString &) const
{
}
#include "moc_kdatevalidator.cpp"
@@ -0,0 +1,42 @@
/* -*- C++ -*-
This file is part of the KDE libraries
SPDX-FileCopyrightText: 1997 Tim D. Gilman <tdgilman@best.org>
SPDX-FileCopyrightText: 1998-2001 Mirko Boehm <mirko@kde.org>
SPDX-FileCopyrightText: 2007 John Layt <john@layt.net>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#ifndef KDATEVALIDATOR_H
#define KDATEVALIDATOR_H
#include <kguiaddons_export.h>
#include <QValidator>
#include <memory>
class KDateValidatorPrivate;
/**
* @class KDateValidator kdatevalidator.h KDateValidator
*
* Validates user-entered dates.
*/
class KGUIADDONS_EXPORT KDateValidator : public QValidator
{
Q_OBJECT
public:
explicit KDateValidator(QObject *parent = nullptr);
~KDateValidator() override;
public:
State validate(QString &text, int &e) const override;
void fixup(QString &input) const override;
State date(const QString &text, QDate &date) const;
private:
std::unique_ptr<KDateValidatorPrivate> const d;
};
#endif // KDATEVALIDATOR_H
@@ -0,0 +1,305 @@
/* This file is part of the KDE libraries
SPDX-FileCopyrightText: 2001 David Faure <faure@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "kwordwrap.h"
#include <QList>
#include <QPainter>
class KWordWrapPrivate : public QSharedData
{
public:
QRect m_constrainingRect;
QList<int> m_breakPositions;
QList<int> m_lineWidths;
QRect m_boundingRect;
QString m_text;
};
KWordWrap::KWordWrap(const QRect &r)
: d(new KWordWrapPrivate)
{
d->m_constrainingRect = r;
}
KWordWrap KWordWrap::formatText(QFontMetrics &fm, const QRect &r, int /*flags*/, const QString &str, int len)
{
KWordWrap kw(r);
// The wordwrap algorithm
// The variable names and the global shape of the algorithm are inspired
// from QTextFormatterBreakWords::format().
// qDebug() << "KWordWrap::formatText " << str << " r=" << r.x() << "," << r.y() << " " << r.width() << "x" << r.height();
int height = fm.height();
if (len == -1) {
kw.d->m_text = str;
} else {
kw.d->m_text = str.left(len);
}
if (len == -1) {
len = str.length();
}
int lastBreak = -1;
int lineWidth = 0;
int x = 0;
int y = 0;
int w = r.width();
int textwidth = 0;
bool isBreakable = false;
bool wasBreakable = false; // value of isBreakable for last char (i-1)
bool isParens = false; // true if one of ({[
bool wasParens = false; // value of isParens for last char (i-1)
QString inputString = str;
for (int i = 0; i < len; ++i) {
const QChar c = inputString.at(i);
const int ww = fm.horizontalAdvance(c);
isParens = (c == QLatin1Char('(') //
|| c == QLatin1Char('[') //
|| c == QLatin1Char('{'));
// isBreakable is true when we can break _after_ this character.
isBreakable = (c.isSpace() || c.isPunct() || c.isSymbol()) & !isParens;
// Special case for '(', '[' and '{': we want to break before them
if (!isBreakable && i < len - 1) {
const QChar nextc = inputString.at(i + 1); // look at next char
isBreakable = (nextc == QLatin1Char('(') //
|| nextc == QLatin1Char('[') //
|| nextc == QLatin1Char('{'));
}
// Special case for '/': after normal chars it's breakable (e.g. inside a path),
// but after another breakable char it's not (e.g. "mounted at /foo")
// Same thing after a parenthesis (e.g. "dfaure [/fool]")
if (c == QLatin1Char('/') && (wasBreakable || wasParens)) {
isBreakable = false;
}
/*qDebug() << "c='" << QString(c) << "' i=" << i << "/" << len
<< " x=" << x << " ww=" << ww << " w=" << w
<< " lastBreak=" << lastBreak << " isBreakable=" << isBreakable << endl;*/
int breakAt = -1;
if (x + ww > w && lastBreak != -1) { // time to break and we know where
breakAt = lastBreak;
}
if (x + ww > w - 4 && lastBreak == -1) { // time to break but found nowhere [-> break here]
breakAt = i;
}
if (i == len - 2 && x + ww + fm.horizontalAdvance(inputString.at(i + 1)) > w) { // don't leave the last char alone
breakAt = lastBreak == -1 ? i - 1 : lastBreak;
}
if (c == QLatin1Char('\n')) { // Forced break here
if (breakAt == -1 && lastBreak != -1) { // only break if not already breaking
breakAt = i - 1;
lastBreak = -1;
}
// remove the line feed from the string
kw.d->m_text.remove(i, 1);
inputString.remove(i, 1);
len--;
}
if (breakAt != -1) {
// qDebug() << "KWordWrap::formatText breaking after " << breakAt;
kw.d->m_breakPositions.append(breakAt);
int thisLineWidth = lastBreak == -1 ? x + ww : lineWidth;
kw.d->m_lineWidths.append(thisLineWidth);
textwidth = qMax(textwidth, thisLineWidth);
x = 0;
y += height;
wasBreakable = true;
wasParens = false;
if (lastBreak != -1) {
// Breakable char was found, restart from there
i = lastBreak;
lastBreak = -1;
continue;
}
} else if (isBreakable) {
lastBreak = i;
lineWidth = x + ww;
}
x += ww;
wasBreakable = isBreakable;
wasParens = isParens;
}
textwidth = qMax(textwidth, x);
kw.d->m_lineWidths.append(x);
y += height;
// qDebug() << "KWordWrap::formatText boundingRect:" << r.x() << "," << r.y() << " " << textwidth << "x" << y;
if (r.height() >= 0 && y > r.height()) {
textwidth = r.width();
}
int realY = y;
if (r.height() >= 0) {
while (realY > r.height()) {
realY -= height;
}
realY = qMax(realY, 0);
}
kw.d->m_boundingRect.setRect(0, 0, textwidth, realY);
return kw;
}
KWordWrap::~KWordWrap()
{
}
KWordWrap::KWordWrap(const KWordWrap &other)
: d(other.d)
{
}
KWordWrap &KWordWrap::operator=(const KWordWrap &other)
{
d = other.d;
return *this;
}
QString KWordWrap::wrappedString() const
{
const QStringView strView(d->m_text);
// We use the calculated break positions to insert '\n' into the string
QString ws;
int start = 0;
for (int i = 0; i < d->m_breakPositions.count(); ++i) {
int end = d->m_breakPositions.at(i);
ws += strView.mid(start, end - start + 1);
ws += QLatin1Char('\n');
start = end + 1;
}
ws += strView.mid(start);
return ws;
}
QString KWordWrap::truncatedString(bool dots) const
{
if (d->m_breakPositions.isEmpty()) {
return d->m_text;
}
QString ts = d->m_text.left(d->m_breakPositions.first() + 1);
if (dots) {
ts += QLatin1String("...");
}
return ts;
}
static QColor mixColors(double p1, QColor c1, QColor c2)
{
return QColor(int(c1.red() * p1 + c2.red() * (1.0 - p1)), //
int(c1.green() * p1 + c2.green() * (1.0 - p1)), //
int(c1.blue() * p1 + c2.blue() * (1.0 - p1)));
}
void KWordWrap::drawFadeoutText(QPainter *p, int x, int y, int maxW, const QString &t)
{
QFontMetrics fm = p->fontMetrics();
QColor bgColor = p->background().color();
QColor textColor = p->pen().color();
if ((fm.boundingRect(t).width() > maxW) && (t.length() > 1)) {
int tl = 0;
int w = 0;
while (tl < t.length()) {
w += fm.horizontalAdvance(t.at(tl));
if (w >= maxW) {
break;
}
tl++;
}
int n = qMin(tl, 3);
if (t.isRightToLeft()) {
x += maxW; // start from the right side for RTL string
if (tl > 3) {
x -= fm.horizontalAdvance(t.left(tl - 3));
p->drawText(x, y, t.left(tl - 3));
}
for (int i = 0; i < n; i++) {
p->setPen(mixColors(0.70 - i * 0.25, textColor, bgColor));
QString s(t.at(tl - n + i));
x -= fm.horizontalAdvance(s);
p->drawText(x, y, s);
}
} else {
if (tl > 3) {
p->drawText(x, y, t.left(tl - 3));
x += fm.horizontalAdvance(t.left(tl - 3));
}
for (int i = 0; i < n; i++) {
p->setPen(mixColors(0.70 - i * 0.25, textColor, bgColor));
QString s(t.at(tl - n + i));
p->drawText(x, y, s);
x += fm.horizontalAdvance(s);
}
}
} else {
p->drawText(x, y, t);
}
}
void KWordWrap::drawTruncateText(QPainter *p, int x, int y, int maxW, const QString &t)
{
QString tmpText = p->fontMetrics().elidedText(t, Qt::ElideRight, maxW);
p->drawText(x, y, tmpText);
}
void KWordWrap::drawText(QPainter *painter, int textX, int textY, int flags) const
{
// qDebug() << "KWordWrap::drawText text=" << wrappedString() << " x=" << textX << " y=" << textY;
// We use the calculated break positions to draw the text line by line using QPainter
int start = 0;
int y = 0;
QFontMetrics fm = painter->fontMetrics();
int height = fm.height(); // line height
int ascent = fm.ascent();
int maxwidth = d->m_boundingRect.width();
int i;
int lwidth = 0;
int end = 0;
for (i = 0; i < d->m_breakPositions.count(); ++i) {
// if this is the last line, leave the loop
if (d->m_constrainingRect.height() >= 0 //
&& ((y + 2 * height) > d->m_constrainingRect.height())) {
break;
}
end = d->m_breakPositions.at(i);
lwidth = d->m_lineWidths.at(i);
int x = textX;
if (flags & Qt::AlignHCenter) {
x += (maxwidth - lwidth) / 2;
} else if (flags & Qt::AlignRight) {
x += maxwidth - lwidth;
}
painter->drawText(x, textY + y + ascent, d->m_text.mid(start, end - start + 1));
y += height;
start = end + 1;
}
// Draw the last line
lwidth = d->m_lineWidths.last();
int x = textX;
if (flags & Qt::AlignHCenter) {
x += (maxwidth - lwidth) / 2;
} else if (flags & Qt::AlignRight) {
x += maxwidth - lwidth;
}
if ((d->m_constrainingRect.height() < 0) || ((y + height) <= d->m_constrainingRect.height())) {
if (i == d->m_breakPositions.count()) {
painter->drawText(x, textY + y + ascent, d->m_text.mid(start));
} else if (flags & FadeOut) {
drawFadeoutText(painter, textX, textY + y + ascent, d->m_constrainingRect.width(), d->m_text.mid(start));
} else if (flags & Truncate) {
drawTruncateText(painter, textX, textY + y + ascent, d->m_constrainingRect.width(), d->m_text.mid(start));
} else {
painter->drawText(x, textY + y + ascent, d->m_text.mid(start));
}
}
}
QRect KWordWrap::boundingRect() const
{
return d->m_boundingRect;
}
@@ -0,0 +1,146 @@
/* This file is part of the KDE libraries
SPDX-FileCopyrightText: 2001 David Faure <faure@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#ifndef kwordwrap_h
#define kwordwrap_h
#include <kguiaddons_export.h>
#include <QSharedDataPointer>
#include <qnamespace.h>
class QFontMetrics;
class QRect;
class QString;
class QPainter;
class KWordWrapPrivate;
/**
* @class KWordWrap kwordwrap.h KWordWrap
*
* Word-wrap algorithm that takes into account beautifulness ;)
*
* That means:
* @li not letting a letter alone on the last line,
* @li breaking at punctuation signs (not only at spaces)
* @li improved handling of (), [] and {}
* @li improved handling of '/' (e.g. for paths)
*
* Usage: call the static method, formatText, with the text to
* wrap and the constraining rectangle etc., it will return an instance of KWordWrap
* containing internal data, result of the word-wrapping.
* From that instance you can retrieve the boundingRect, and invoke drawing.
*
* This design allows to call the word-wrap algorithm only when the text changes
* and not every time we want to know the bounding rect or draw the text.
*
* @author David Faure <faure@kde.org>
*/
class KGUIADDONS_EXPORT KWordWrap
{
public:
/**
* Use this flag in drawText() if you want to fade out the text if it does
* not fit into the constraining rectangle.
*/
enum {
FadeOut = 0x10000000,
Truncate = 0x20000000,
};
/**
* Main method for wrapping text.
*
* @param fm Font metrics, for the chosen font. Better cache it, creating a QFontMetrics is expensive.
* @param r Constraining rectangle. Only the width and height matter. With
* negative height the complete text will be rendered
* @param flags currently unused
* @param str The text to be wrapped.
* @param len Length of text to wrap (default is -1 for all).
* @return a KWordWrap instance. The caller is responsible for storing and deleting the result.
*/
static KWordWrap formatText(QFontMetrics &fm, const QRect &r, int flags, const QString &str, int len = -1);
/**
* @return the bounding rect, calculated by formatText. The width is the
* width of the widest text line, and never wider than
* the rectangle given to formatText. The height is the
* text block. X and Y are always 0.
*/
QRect boundingRect() const;
/**
* @return the original string, with '\n' inserted where
* the text is broken by the wordwrap algorithm.
*/
QString wrappedString() const; // gift for Dirk :)
/**
* @return the original string, truncated to the first line.
* If @p dots was set, '...' is appended in case the string was truncated.
* Bug: Note that the '...' come out of the bounding rect.
*/
QString truncatedString(bool dots = true) const;
/**
* Draw the text that has been previously wrapped, at position x,y.
* Flags are for alignment, e.g. Qt::AlignHCenter. Default is
* Qt::AlignAuto.
* @param painter the QPainter to use.
* @param x the horizontal position of the text
* @param y the vertical position of the text
* @param flags the ORed text alignment flags from the Qt namespace,
* ORed with FadeOut if you want the text to fade out if it
* does not fit (the @p painter's background must be set
* accordingly)
*/
void drawText(QPainter *painter, int x, int y, int flags = Qt::AlignLeft) const;
/**
* Destructor.
*/
~KWordWrap();
/**
* Copy constructor
*/
KWordWrap(const KWordWrap &other);
/**
* Assignment operator
*/
KWordWrap &operator=(const KWordWrap &other);
/**
* Draws the string @p t at the given coordinates, if it does not
* @p fit into @p maxW the text will be faded out.
* @param p the painter to use. Must have set the pen for the text
* color and the background for the color to fade out
* @param x the horizontal position of the text
* @param y the vertical position of the text
* @param maxW the maximum width of the text (including the fade-out
* effect)
* @param t the text to draw
*/
static void drawFadeoutText(QPainter *p, int x, int y, int maxW, const QString &t);
/**
* Draws the string @p t at the given coordinates, if it does not
* @p fit into @p maxW the text will be truncated.
* @param p the painter to use
* @param x the horizontal position of the text
* @param y the vertical position of the text
* @param maxW the maximum width of the text (including the '...')
* @param t the text to draw
*/
static void drawTruncateText(QPainter *p, int x, int y, int maxW, const QString &t);
private:
KGUIADDONS_NO_EXPORT explicit KWordWrap(const QRect &r);
QExplicitlySharedDataPointer<KWordWrapPrivate> d;
};
#endif