QColorDialog: Support hex rgb values with and without leading #
QColorDialog supports entering hex rgb values only with a leading #. That makes copy/paste impossible whenever the copy source has plain hex, without the leading #. This patch automatically adds a leading # character, when missing. As a drive-by, QObject::connect statements are altered to PTMF syntax, amending 9eb1b9e86ce3d1004e39e8ab7c7ecb6796d6df1a. The patch also adds an autotest for the new functionality. Fixes: QTBUG-111742 Pick-to: 6.5 Change-Id: I4ced29dc8b543457f411a3fa0ac756b550cdb09f Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
parent
f03fedfaec
commit
b04f9388ac
@ -1180,8 +1180,8 @@ QColorShower::QColorShower(QColorDialog *parent)
|
|||||||
#else
|
#else
|
||||||
gl->addWidget(lab, 0, 0, 1, -1);
|
gl->addWidget(lab, 0, 0, 1, -1);
|
||||||
#endif
|
#endif
|
||||||
connect(lab, SIGNAL(colorDropped(QRgb)), this, SIGNAL(newCol(QRgb)));
|
connect(lab, &QColorShowLabel::colorDropped, this, &QColorShower::newCol);
|
||||||
connect(lab, SIGNAL(colorDropped(QRgb)), this, SLOT(setRgb(QRgb)));
|
connect(lab, &QColorShowLabel::colorDropped, this, &QColorShower::setRgb);
|
||||||
|
|
||||||
hEd = new QColSpinBox(this);
|
hEd = new QColSpinBox(this);
|
||||||
hEd->setRange(0, 359);
|
hEd->setRange(0, 359);
|
||||||
@ -1285,12 +1285,13 @@ QColorShower::QColorShower(QColorDialog *parent)
|
|||||||
alphaLab->hide();
|
alphaLab->hide();
|
||||||
lblHtml = new QLabel(this);
|
lblHtml = new QLabel(this);
|
||||||
htEd = new QLineEdit(this);
|
htEd = new QLineEdit(this);
|
||||||
|
htEd->setObjectName("qt_colorname_lineedit");
|
||||||
#ifndef QT_NO_SHORTCUT
|
#ifndef QT_NO_SHORTCUT
|
||||||
lblHtml->setBuddy(htEd);
|
lblHtml->setBuddy(htEd);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if QT_CONFIG(regularexpression)
|
#if QT_CONFIG(regularexpression)
|
||||||
QRegularExpression regExp(QStringLiteral("#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})"));
|
QRegularExpression regExp(QStringLiteral("#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})"));
|
||||||
QRegularExpressionValidator *validator = new QRegularExpressionValidator(regExp, this);
|
QRegularExpressionValidator *validator = new QRegularExpressionValidator(regExp, this);
|
||||||
htEd->setValidator(validator);
|
htEd->setValidator(validator);
|
||||||
#else
|
#else
|
||||||
@ -1307,15 +1308,15 @@ QColorShower::QColorShower(QColorDialog *parent)
|
|||||||
gl->addWidget(htEd, 5, 2, 1, /*colspan=*/ 3);
|
gl->addWidget(htEd, 5, 2, 1, /*colspan=*/ 3);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
connect(hEd, SIGNAL(valueChanged(int)), this, SLOT(hsvEd()));
|
connect(hEd, &QSpinBox::valueChanged, this, &QColorShower::hsvEd);
|
||||||
connect(sEd, SIGNAL(valueChanged(int)), this, SLOT(hsvEd()));
|
connect(sEd, &QSpinBox::valueChanged, this, &QColorShower::hsvEd);
|
||||||
connect(vEd, SIGNAL(valueChanged(int)), this, SLOT(hsvEd()));
|
connect(vEd, &QSpinBox::valueChanged, this, &QColorShower::hsvEd);
|
||||||
|
|
||||||
connect(rEd, SIGNAL(valueChanged(int)), this, SLOT(rgbEd()));
|
connect(rEd, &QSpinBox::valueChanged, this, &QColorShower::rgbEd);
|
||||||
connect(gEd, SIGNAL(valueChanged(int)), this, SLOT(rgbEd()));
|
connect(gEd, &QSpinBox::valueChanged, this, &QColorShower::rgbEd);
|
||||||
connect(bEd, SIGNAL(valueChanged(int)), this, SLOT(rgbEd()));
|
connect(bEd, &QSpinBox::valueChanged, this, &QColorShower::rgbEd);
|
||||||
connect(alphaEd, SIGNAL(valueChanged(int)), this, SLOT(rgbEd()));
|
connect(alphaEd, &QSpinBox::valueChanged, this, &QColorShower::rgbEd);
|
||||||
connect(htEd, SIGNAL(textEdited(QString)), this, SLOT(htmlEd()));
|
connect(htEd, &QLineEdit::textChanged, this, &QColorShower::htmlEd);
|
||||||
|
|
||||||
retranslateStrings();
|
retranslateStrings();
|
||||||
}
|
}
|
||||||
@ -1384,9 +1385,19 @@ void QColorShower::hsvEd()
|
|||||||
void QColorShower::htmlEd()
|
void QColorShower::htmlEd()
|
||||||
{
|
{
|
||||||
QString t = htEd->text();
|
QString t = htEd->text();
|
||||||
|
if (t.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!t.startsWith(QStringLiteral("#"))) {
|
||||||
|
t = QStringLiteral("#") + t;
|
||||||
|
QSignalBlocker blocker(htEd);
|
||||||
|
htEd->setText(t);
|
||||||
|
}
|
||||||
|
|
||||||
QColor c = QColor::fromString(t);
|
QColor c = QColor::fromString(t);
|
||||||
if (!c.isValid())
|
if (!c.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
curCol = qRgba(c.red(), c.green(), c.blue(), currentAlpha());
|
curCol = qRgba(c.red(), c.green(), c.blue(), currentAlpha());
|
||||||
rgb2hsv(curCol, hue, sat, val);
|
rgb2hsv(curCol, hue, sat, val);
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
#include <QTest>
|
#include <QTest>
|
||||||
#include <QtGui/QtGui>
|
#include <QtGui/QtGui>
|
||||||
#include <QtWidgets/QColorDialog>
|
#include <QtWidgets/QColorDialog>
|
||||||
|
#include <QtWidgets/QLineEdit>
|
||||||
|
#include <QSignalSpy>
|
||||||
|
|
||||||
QT_FORWARD_DECLARE_CLASS(QtTestEventThread)
|
QT_FORWARD_DECLARE_CLASS(QtTestEventThread)
|
||||||
|
|
||||||
@ -25,6 +27,8 @@ private slots:
|
|||||||
void native_activeModalWidget();
|
void native_activeModalWidget();
|
||||||
void task247349_alpha();
|
void task247349_alpha();
|
||||||
void QTBUG_43548_initialColor();
|
void QTBUG_43548_initialColor();
|
||||||
|
void hexColor_data();
|
||||||
|
void hexColor();
|
||||||
};
|
};
|
||||||
|
|
||||||
class TestNativeDialog : public QColorDialog
|
class TestNativeDialog : public QColorDialog
|
||||||
@ -126,5 +130,54 @@ void tst_QColorDialog::QTBUG_43548_initialColor()
|
|||||||
QCOMPARE(a, dialog.currentColor());
|
QCOMPARE(a, dialog.currentColor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QColorDialog::hexColor_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<const QString>("colorString");
|
||||||
|
QTest::addColumn<const QString>("expectedHexColor");
|
||||||
|
QTest::addColumn<const int>("expectedSignalCount");
|
||||||
|
|
||||||
|
QTest::newRow("White-#") << "#FFFFFE" << "#FFFFFE" << 1;
|
||||||
|
QTest::newRow("White") << "FFFFFD" << "#FFFFFD" << 1;
|
||||||
|
QTest::newRow("Blue-#") << "#77fffb" << "#77fffb" << 2;
|
||||||
|
QTest::newRow("Blue") << "77fffa" << "#77fffa" << 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QColorDialog::hexColor()
|
||||||
|
{
|
||||||
|
QColorDialog dialog;
|
||||||
|
dialog.setOption(QColorDialog::DontUseNativeDialog);
|
||||||
|
dialog.show();
|
||||||
|
QVERIFY(QTest::qWaitForWindowExposed(&dialog));
|
||||||
|
|
||||||
|
QLineEdit *lineEdit = dialog.findChild<QLineEdit *>("qt_colorname_lineedit",
|
||||||
|
Qt::FindChildrenRecursively);
|
||||||
|
QVERIFY2(lineEdit, "QLineEdit for color not found. Adapt this test.");
|
||||||
|
QVERIFY(lineEdit); // eliminate compiler warning
|
||||||
|
|
||||||
|
QFETCH(const QString, colorString);
|
||||||
|
QFETCH(const QString, expectedHexColor);
|
||||||
|
QFETCH(const int, expectedSignalCount);
|
||||||
|
|
||||||
|
QSignalSpy spy(&dialog, &QColorDialog::currentColorChanged);
|
||||||
|
|
||||||
|
// Delete existing color
|
||||||
|
lineEdit->activateWindow();
|
||||||
|
QVERIFY(QTest::qWaitForWindowActive(lineEdit));
|
||||||
|
for (int i = 0; i < 8; ++i)
|
||||||
|
QTest::keyEvent(QTest::KeyAction::Click, lineEdit, Qt::Key_Backspace);
|
||||||
|
QVERIFY(lineEdit->text().isEmpty());
|
||||||
|
|
||||||
|
// Enter new color
|
||||||
|
for (const QChar &key : colorString)
|
||||||
|
QTest::keyEvent(QTest::KeyAction::Click, lineEdit, key.toLatin1());
|
||||||
|
QCOMPARE(lineEdit->text().toLower(), expectedHexColor.toLower());
|
||||||
|
|
||||||
|
// Consume all color change signals
|
||||||
|
QTRY_COMPARE(spy.count(), expectedSignalCount);
|
||||||
|
|
||||||
|
const QColor color = qvariant_cast<QColor>(spy.last().at(0));
|
||||||
|
QCOMPARE(color.name(QColor::HexRgb), expectedHexColor.toLower());
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QColorDialog)
|
QTEST_MAIN(tst_QColorDialog)
|
||||||
#include "tst_qcolordialog.moc"
|
#include "tst_qcolordialog.moc"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user