File indexing completed on 2024-05-05 03:48:37

0001 /*
0002     File                 : SpinBoxTest.cpp
0003     Project              : LabPlot
0004     Description          : Tests for spinbox widgets
0005     --------------------------------------------------------------------
0006     SPDX-FileCopyrightText: 2022 Martin Marmsoler <martin.marmsoler@gmail.com>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 
0011 #include "SpinBoxTest.h"
0012 #include "backend/core/Project.h"
0013 #include "backend/worksheet/Worksheet.h"
0014 #include "backend/worksheet/plots/cartesian/CartesianPlot.h"
0015 #include "backend/worksheet/plots/cartesian/XYEquationCurve.h"
0016 #include "commonfrontend/widgets/NumberSpinBox.h"
0017 #include "src/kdefrontend/dockwidgets/CartesianPlotDock.h"
0018 
0019 #include <QLineEdit>
0020 #include <QLocale>
0021 
0022 void SpinBoxTest::numberSpinBoxProperties() {
0023     {
0024         NumberSpinBox sb;
0025         NumberSpinBox::NumberProperties p;
0026         QCOMPARE(sb.properties(QStringLiteral("133"), p), true);
0027         QCOMPARE(p.integerSign, QChar::Null);
0028         QCOMPARE(p.integer, 133);
0029         QCOMPARE(p.intergerDigits, 3);
0030         QCOMPARE(p.fraction, false);
0031         // QCOMPARE(p.fractionDigits, 0);
0032         QCOMPARE(p.exponentLetter, QChar::Null);
0033         // exponents are invalid
0034     }
0035 
0036     {
0037         NumberSpinBox sb;
0038         NumberSpinBox::NumberProperties p;
0039         QCOMPARE(sb.properties(QStringLiteral("+133"), p), true);
0040         QCOMPARE(p.integerSign, QLatin1Char('+'));
0041         QCOMPARE(p.integer, 133);
0042         QCOMPARE(p.intergerDigits, 3);
0043         QCOMPARE(p.fraction, false);
0044         // QCOMPARE(p.fractionDigits, 0);
0045         QCOMPARE(p.exponentLetter, QChar::Null);
0046         // exponents are invalid
0047     }
0048 
0049     {
0050         NumberSpinBox sb;
0051         NumberSpinBox::NumberProperties p;
0052         QCOMPARE(sb.properties(QStringLiteral("-122129"), p), true);
0053         QCOMPARE(p.integerSign, QLatin1Char('-'));
0054         QCOMPARE(p.integer, 122129);
0055         QCOMPARE(p.intergerDigits, 6);
0056         QCOMPARE(p.fraction, false);
0057         // QCOMPARE(p.fractionDigits, 0);
0058         QCOMPARE(p.exponentLetter, QChar::Null);
0059         // exponents are invalid
0060     }
0061 
0062     {
0063         NumberSpinBox sb;
0064         NumberSpinBox::NumberProperties p;
0065         sb.setLocale(QLocale(QLocale::Language::English));
0066         QCOMPARE(sb.properties(QStringLiteral("123.348"), p), true);
0067         QCOMPARE(p.integerSign, QChar::Null);
0068         QCOMPARE(p.integer, 123);
0069         QCOMPARE(p.intergerDigits, 3);
0070         QCOMPARE(p.fraction, true);
0071         QCOMPARE(p.fractionPos, 3);
0072         QCOMPARE(p.fractionDigits, 3);
0073         QCOMPARE(p.exponentLetter, QChar::Null);
0074         // exponents are invalid
0075     }
0076 
0077     {
0078         NumberSpinBox sb;
0079         sb.setLocale(QLocale(QLocale::Language::English));
0080         NumberSpinBox::NumberProperties p;
0081         QCOMPARE(sb.properties(QStringLiteral("+13832.283"), p), true);
0082         QCOMPARE(p.integerSign, QLatin1Char('+'));
0083         QCOMPARE(p.integer, 13832);
0084         QCOMPARE(p.intergerDigits, 5);
0085         QCOMPARE(p.fraction, true);
0086         QCOMPARE(p.fractionPos, 6);
0087         QCOMPARE(p.fractionDigits, 3);
0088         QCOMPARE(p.exponentLetter, QChar::Null);
0089         // exponents are invalid
0090     }
0091 
0092     {
0093         NumberSpinBox sb;
0094         sb.setLocale(QLocale(QLocale::Language::English));
0095         NumberSpinBox::NumberProperties p;
0096         QCOMPARE(sb.properties(QStringLiteral("-13832.283"), p), true);
0097         QCOMPARE(p.integerSign, QLatin1Char('-'));
0098         QCOMPARE(p.integer, 13832);
0099         QCOMPARE(p.intergerDigits, 5);
0100         QCOMPARE(p.fraction, true);
0101         QCOMPARE(p.fractionPos, 6);
0102         QCOMPARE(p.fractionDigits, 3);
0103         QCOMPARE(p.exponentLetter, QChar::Null);
0104         // exponents are invalid
0105     }
0106 
0107     // without any number after comma
0108     {
0109         NumberSpinBox sb;
0110         sb.setLocale(QLocale(QLocale::Language::English));
0111         NumberSpinBox::NumberProperties p;
0112         QCOMPARE(sb.properties(QStringLiteral("14323."), p), true);
0113         QCOMPARE(p.integerSign, QChar::Null);
0114         QCOMPARE(p.integer, 14323);
0115         QCOMPARE(p.intergerDigits, 5);
0116         QCOMPARE(p.fraction, true);
0117         QCOMPARE(p.fractionPos, 5);
0118         QCOMPARE(p.fractionDigits, 0);
0119         QCOMPARE(p.exponentLetter, QChar::Null);
0120         // exponents are invalid
0121     }
0122 
0123     {
0124         NumberSpinBox sb;
0125         sb.setLocale(QLocale(QLocale::Language::English));
0126         NumberSpinBox::NumberProperties p;
0127         QCOMPARE(sb.properties(QStringLiteral("+1334832."), p), true);
0128         QCOMPARE(p.integerSign, QLatin1Char('+'));
0129         QCOMPARE(p.integer, 1334832);
0130         QCOMPARE(p.intergerDigits, 7);
0131         QCOMPARE(p.fraction, true);
0132         QCOMPARE(p.fractionPos, 8);
0133         QCOMPARE(p.fractionDigits, 0);
0134         QCOMPARE(p.exponentLetter, QChar::Null);
0135         // exponents are invalid
0136     }
0137 
0138     {
0139         NumberSpinBox sb;
0140         sb.setLocale(QLocale(QLocale::Language::English));
0141         NumberSpinBox::NumberProperties p;
0142         QCOMPARE(sb.properties(QStringLiteral("-13823432."), p), true);
0143         QCOMPARE(p.integerSign, QLatin1Char('-'));
0144         QCOMPARE(p.integer, 13823432);
0145         QCOMPARE(p.intergerDigits, 8);
0146         QCOMPARE(p.fraction, true);
0147         QCOMPARE(p.fractionPos, 9);
0148         QCOMPARE(p.fractionDigits, 0);
0149         QCOMPARE(p.exponentLetter, QChar::Null);
0150         // exponents are invalid
0151     }
0152 
0153     // exponent
0154     {
0155         NumberSpinBox sb;
0156         sb.setLocale(QLocale(QLocale::Language::English));
0157         NumberSpinBox::NumberProperties p;
0158         QCOMPARE(sb.properties(QStringLiteral("123.348E001"), p), true);
0159         QCOMPARE(p.integerSign, QChar::Null);
0160         QCOMPARE(p.integer, 123);
0161         QCOMPARE(p.intergerDigits, 3);
0162         QCOMPARE(p.fraction, true);
0163         QCOMPARE(p.fractionPos, 3);
0164         QCOMPARE(p.fractionDigits, 3);
0165         QCOMPARE(p.exponentLetter, QLatin1Char('E'));
0166         QCOMPARE(p.exponentPos, 7);
0167         QCOMPARE(p.exponentSign, QChar::Null);
0168         QCOMPARE(p.exponent, 1);
0169         QCOMPARE(p.exponentDigits, 3);
0170     }
0171 
0172     {
0173         NumberSpinBox sb;
0174         sb.setLocale(QLocale(QLocale::Language::English));
0175         NumberSpinBox::NumberProperties p;
0176         QCOMPARE(sb.properties(QStringLiteral("+13832.283E012"), p), true);
0177         QCOMPARE(p.integerSign, QLatin1Char('+'));
0178         QCOMPARE(p.integer, 13832);
0179         QCOMPARE(p.intergerDigits, 5);
0180         QCOMPARE(p.fraction, true);
0181         QCOMPARE(p.fractionPos, 6);
0182         QCOMPARE(p.fractionDigits, 3);
0183         QCOMPARE(p.exponentLetter, QLatin1Char('E'));
0184         QCOMPARE(p.exponentPos, 10);
0185         QCOMPARE(p.exponentSign, QChar::Null);
0186         QCOMPARE(p.exponent, 12);
0187         QCOMPARE(p.exponentDigits, 3);
0188     }
0189 
0190     {
0191         NumberSpinBox sb;
0192         sb.setLocale(QLocale(QLocale::Language::English));
0193         NumberSpinBox::NumberProperties p;
0194         QCOMPARE(sb.properties(QStringLiteral("-13832.283E99"), p), true);
0195         QCOMPARE(p.integerSign, QLatin1Char('-'));
0196         QCOMPARE(p.integer, 13832);
0197         QCOMPARE(p.intergerDigits, 5);
0198         QCOMPARE(p.fraction, true);
0199         QCOMPARE(p.fractionPos, 6);
0200         QCOMPARE(p.fractionDigits, 3);
0201         QCOMPARE(p.exponentLetter, QLatin1Char('E'));
0202         QCOMPARE(p.exponentPos, 10);
0203         QCOMPARE(p.exponentSign, QChar::Null);
0204         QCOMPARE(p.exponent, 99);
0205         QCOMPARE(p.exponentDigits, 2);
0206     }
0207 
0208     {
0209         NumberSpinBox sb;
0210         sb.setLocale(QLocale(QLocale::Language::English));
0211         NumberSpinBox::NumberProperties p;
0212         QCOMPARE(sb.properties(QStringLiteral("123.348e-001"), p), true);
0213         QCOMPARE(p.integerSign, QChar::Null);
0214         QCOMPARE(p.integer, 123);
0215         QCOMPARE(p.intergerDigits, 3);
0216         QCOMPARE(p.fraction, true);
0217         QCOMPARE(p.fractionPos, 3);
0218         QCOMPARE(p.fractionDigits, 3);
0219         QCOMPARE(p.exponentLetter, QLatin1Char('e'));
0220         QCOMPARE(p.exponentPos, 7);
0221         QCOMPARE(p.exponentSign, QLatin1Char('-'));
0222         QCOMPARE(p.exponent, 1);
0223         QCOMPARE(p.exponentDigits, 3);
0224     }
0225 
0226     {
0227         NumberSpinBox sb;
0228         sb.setLocale(QLocale(QLocale::Language::English));
0229         NumberSpinBox::NumberProperties p;
0230         QCOMPARE(sb.properties(QStringLiteral("+13832.283e-012"), p), true);
0231         QCOMPARE(p.integerSign, QLatin1Char('+'));
0232         QCOMPARE(p.integer, 13832);
0233         QCOMPARE(p.intergerDigits, 5);
0234         QCOMPARE(p.fraction, true);
0235         QCOMPARE(p.fractionPos, 6);
0236         QCOMPARE(p.fractionDigits, 3);
0237         QCOMPARE(p.exponentLetter, QLatin1Char('e'));
0238         QCOMPARE(p.exponentPos, 10);
0239         QCOMPARE(p.exponentSign, QLatin1Char('-'));
0240         QCOMPARE(p.exponent, 12);
0241         QCOMPARE(p.exponentDigits, 3);
0242     }
0243 
0244     {
0245         NumberSpinBox sb;
0246         sb.setLocale(QLocale(QLocale::Language::English));
0247         NumberSpinBox::NumberProperties p;
0248         QCOMPARE(sb.properties(QStringLiteral("-13832.283e-123"), p), true);
0249         QCOMPARE(p.integerSign, QLatin1Char('-'));
0250         QCOMPARE(p.integer, 13832);
0251         QCOMPARE(p.intergerDigits, 5);
0252         QCOMPARE(p.fraction, true);
0253         QCOMPARE(p.fractionPos, 6);
0254         QCOMPARE(p.fractionDigits, 3);
0255         QCOMPARE(p.exponentLetter, QLatin1Char('e'));
0256         QCOMPARE(p.exponentPos, 10);
0257         QCOMPARE(p.exponentSign, QLatin1Char('-'));
0258         QCOMPARE(p.exponent, 123);
0259         QCOMPARE(p.exponentDigits, 3);
0260     }
0261 
0262     {
0263         NumberSpinBox sb;
0264         sb.setLocale(QLocale(QLocale::Language::English));
0265         NumberSpinBox::NumberProperties p;
0266         QCOMPARE(sb.properties(QStringLiteral("-13832.283e0"), p), true);
0267         QCOMPARE(p.integerSign, QLatin1Char('-'));
0268         QCOMPARE(p.integer, 13832);
0269         QCOMPARE(p.intergerDigits, 5);
0270         QCOMPARE(p.fraction, true);
0271         QCOMPARE(p.fractionPos, 6);
0272         QCOMPARE(p.fractionDigits, 3);
0273         QCOMPARE(p.exponentLetter, QLatin1Char('e'));
0274         QCOMPARE(p.exponentPos, 10);
0275         QCOMPARE(p.exponentSign, QChar::Null);
0276         QCOMPARE(p.exponent, 0);
0277         QCOMPARE(p.exponentDigits, 1);
0278     }
0279 }
0280 
0281 void SpinBoxTest::numberSpinBoxCreateStringNumber() {
0282     {
0283         NumberSpinBox sb;
0284         NumberSpinBox::NumberProperties p;
0285         QCOMPARE(sb.properties(QStringLiteral("133"), p), true);
0286         QCOMPARE(sb.createStringNumber(143, 0, p), QStringLiteral("143"));
0287     }
0288 
0289     {
0290         NumberSpinBox sb;
0291         NumberSpinBox::NumberProperties p;
0292         QCOMPARE(sb.properties(QStringLiteral("+133"), p), true);
0293         QCOMPARE(sb.createStringNumber(143, 0, p), QStringLiteral("+143"));
0294     }
0295 
0296     {
0297         NumberSpinBox sb;
0298         NumberSpinBox::NumberProperties p;
0299         QCOMPARE(sb.properties(QStringLiteral("-122129"), p), true);
0300         QCOMPARE(sb.createStringNumber(-122129, 0, p), QStringLiteral("-122129"));
0301     }
0302 
0303     {
0304         NumberSpinBox sb;
0305         sb.setLocale(QLocale(QLocale::Language::English));
0306         NumberSpinBox::NumberProperties p;
0307         QCOMPARE(sb.properties(QStringLiteral("123.348"), p), true);
0308         QCOMPARE(sb.createStringNumber(23.348345, 0, p), QStringLiteral("23.348"));
0309     }
0310 
0311     {
0312         NumberSpinBox sb;
0313         sb.setLocale(QLocale(QLocale::Language::English));
0314         NumberSpinBox::NumberProperties p;
0315         QCOMPARE(sb.properties(QStringLiteral("+13832.283"), p), true);
0316         QCOMPARE(sb.createStringNumber(+13732.28, 0, p), QStringLiteral("+13,732.280"));
0317     }
0318 
0319     {
0320         NumberSpinBox sb;
0321         sb.setLocale(QLocale(QLocale::Language::English));
0322         NumberSpinBox::NumberProperties p;
0323         QCOMPARE(sb.properties(QStringLiteral("-13832.283"), p), true);
0324         QCOMPARE(sb.createStringNumber(-13812.28, 0, p), QStringLiteral("-13,812.280"));
0325     }
0326 
0327     // without any number after comma
0328     {
0329         NumberSpinBox sb;
0330         sb.setLocale(QLocale(QLocale::Language::English));
0331         NumberSpinBox::NumberProperties p;
0332         QCOMPARE(sb.properties(QStringLiteral("14323."), p), true);
0333         QCOMPARE(sb.createStringNumber(345., 0, p), QStringLiteral("345."));
0334     }
0335 
0336     {
0337         NumberSpinBox sb;
0338         sb.setLocale(QLocale(QLocale::Language::English));
0339         NumberSpinBox::NumberProperties p;
0340         QCOMPARE(sb.properties(QStringLiteral("+1334832."), p), true);
0341         QCOMPARE(sb.createStringNumber(+345., 0, p), QStringLiteral("+345."));
0342     }
0343 
0344     {
0345         NumberSpinBox sb;
0346         sb.setLocale(QLocale(QLocale::Language::English));
0347         NumberSpinBox::NumberProperties p;
0348         QCOMPARE(sb.properties(QStringLiteral("-13823432."), p), true);
0349         QCOMPARE(sb.createStringNumber(-45., 0, p), QStringLiteral("-45."));
0350     }
0351 
0352     // exponent
0353     {
0354         NumberSpinBox sb;
0355         sb.setLocale(QLocale(QLocale::Language::English));
0356         NumberSpinBox::NumberProperties p;
0357         QCOMPARE(sb.properties(QStringLiteral("999.348E001"), p), true);
0358         QCOMPARE(sb.createStringNumber(1000.348, 12, p), QStringLiteral("1,000.348E012"));
0359     }
0360 
0361     {
0362         NumberSpinBox sb;
0363         sb.setLocale(QLocale(QLocale::Language::English));
0364         NumberSpinBox::NumberProperties p;
0365         QCOMPARE(sb.properties(QStringLiteral("+13832.283E012"), p), true);
0366         QCOMPARE(sb.createStringNumber(+123.283, 2, p), QStringLiteral("+123.283E002"));
0367     }
0368 
0369     {
0370         NumberSpinBox sb;
0371         sb.setLocale(QLocale(QLocale::Language::English));
0372         NumberSpinBox::NumberProperties p;
0373         QCOMPARE(sb.properties(QStringLiteral("-13832.283E99"), p), true);
0374         QCOMPARE(sb.createStringNumber(-13832.283, 99, p), QStringLiteral("-13,832.283E99"));
0375     }
0376 
0377     {
0378         NumberSpinBox sb;
0379         sb.setLocale(QLocale(QLocale::Language::English));
0380         NumberSpinBox::NumberProperties p;
0381         QCOMPARE(sb.properties(QStringLiteral("123.348e-001"), p), true);
0382         QCOMPARE(sb.createStringNumber(123.348, -12, p), QStringLiteral("123.348e-012"));
0383     }
0384 
0385     {
0386         NumberSpinBox sb;
0387         sb.setLocale(QLocale(QLocale::Language::English));
0388         NumberSpinBox::NumberProperties p;
0389         QCOMPARE(sb.properties(QStringLiteral("+13832.283e-012"), p), true);
0390         QCOMPARE(sb.createStringNumber(+13832.283, -12, p), QStringLiteral("+13,832.283e-012"));
0391     }
0392 
0393     {
0394         NumberSpinBox sb;
0395         sb.setLocale(QLocale(QLocale::Language::English));
0396         NumberSpinBox::NumberProperties p;
0397         QCOMPARE(sb.properties(QStringLiteral("-13832.283e-123"), p), true);
0398         QCOMPARE(sb.createStringNumber(-123.283, -3, p), QStringLiteral("-123.283e-003"));
0399     }
0400 
0401     {
0402         NumberSpinBox sb;
0403         sb.setLocale(QLocale(QLocale::Language::English));
0404         NumberSpinBox::NumberProperties p;
0405         QCOMPARE(sb.properties(QStringLiteral("-13832.283e00"), p), true);
0406         QCOMPARE(sb.createStringNumber(-123.283, 0, p), QStringLiteral("-123.283e00"));
0407     }
0408 }
0409 
0410 void SpinBoxTest::numberSpinBoxChangingValueKeyPress() {
0411     {
0412         NumberSpinBox sb;
0413         sb.lineEdit()->setText(QStringLiteral("3"));
0414         sb.lineEdit()->setCursorPosition(1);
0415         QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_Down, Qt::KeyboardModifier::NoModifier);
0416         sb.keyPressEvent(&event);
0417         VALUES_EQUAL(sb.value(), 2.);
0418         sb.keyPressEvent(&event);
0419         VALUES_EQUAL(sb.value(), 1.);
0420         sb.keyPressEvent(&event);
0421         VALUES_EQUAL(sb.value(), 0.);
0422         sb.keyPressEvent(&event);
0423         VALUES_EQUAL(sb.value(), -1.);
0424         sb.keyPressEvent(&event);
0425         VALUES_EQUAL(sb.value(), -2.);
0426 
0427         QKeyEvent upEvent(QKeyEvent::Type::KeyPress, Qt::Key_Up, Qt::KeyboardModifier::NoModifier);
0428         sb.keyPressEvent(&upEvent);
0429         VALUES_EQUAL(sb.value(), -1.);
0430         sb.keyPressEvent(&upEvent);
0431         VALUES_EQUAL(sb.value(), 0.);
0432         sb.keyPressEvent(&upEvent);
0433         VALUES_EQUAL(sb.value(), 1.);
0434     }
0435 
0436     {
0437         NumberSpinBox sb;
0438         sb.lineEdit()->setText(QStringLiteral("3000"));
0439         sb.lineEdit()->setCursorPosition(2);
0440         QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_Down, Qt::KeyboardModifier::NoModifier);
0441         sb.keyPressEvent(&event);
0442         VALUES_EQUAL(sb.value(), 2900.);
0443         sb.keyPressEvent(&event);
0444         VALUES_EQUAL(sb.value(), 2800.);
0445         sb.keyPressEvent(&event);
0446         VALUES_EQUAL(sb.value(), 2700.);
0447 
0448         QKeyEvent upEvent(QKeyEvent::Type::KeyPress, Qt::Key_Up, Qt::KeyboardModifier::NoModifier);
0449         sb.keyPressEvent(&upEvent);
0450         VALUES_EQUAL(sb.value(), 2800.);
0451         sb.keyPressEvent(&upEvent);
0452         VALUES_EQUAL(sb.value(), 2900.);
0453         sb.keyPressEvent(&upEvent);
0454         VALUES_EQUAL(sb.value(), 3000.);
0455         sb.stepBy(71);
0456         VALUES_EQUAL(sb.value(), 10100.);
0457     }
0458 
0459     {
0460         NumberSpinBox sb;
0461         sb.lineEdit()->setText(QStringLiteral("5e1"));
0462         sb.lineEdit()->setCursorPosition(3);
0463         QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_Down, Qt::KeyboardModifier::NoModifier);
0464         sb.keyPressEvent(&event);
0465         VALUES_EQUAL(sb.value(), 5.e0);
0466         sb.keyPressEvent(&event);
0467         VALUES_EQUAL(sb.value(), 5.e-1);
0468         sb.keyPressEvent(&event);
0469         VALUES_EQUAL(sb.value(), 5.e-2);
0470 
0471         QKeyEvent upEvent(QKeyEvent::Type::KeyPress, Qt::Key_Up, Qt::KeyboardModifier::NoModifier);
0472         sb.keyPressEvent(&upEvent);
0473         VALUES_EQUAL(sb.value(), 5.e-1);
0474         sb.keyPressEvent(&upEvent);
0475         VALUES_EQUAL(sb.value(), 5.e0);
0476     }
0477 
0478     {
0479         NumberSpinBox sb;
0480         sb.setLocale(QLocale(QLocale::Language::English));
0481         sb.lineEdit()->setText(QStringLiteral("5.5e+300"));
0482         sb.lineEdit()->setCursorPosition(7);
0483         QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_Up, Qt::KeyboardModifier::NoModifier);
0484         sb.keyPressEvent(&event);
0485         VALUES_EQUAL(sb.value(), 5.5e+307);
0486     }
0487 
0488     {
0489         NumberSpinBox sb;
0490         sb.setLocale(QLocale(QLocale::Language::English));
0491         sb.lineEdit()->setText(QStringLiteral("1.6e+300"));
0492         sb.lineEdit()->setCursorPosition(7);
0493         QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_Up, Qt::KeyboardModifier::NoModifier);
0494         sb.keyPressEvent(&event);
0495         VALUES_EQUAL(sb.value(), 1.6e+308);
0496     }
0497 
0498     {
0499         NumberSpinBox sb;
0500         sb.setLocale(QLocale(QLocale::Language::English));
0501         sb.lineEdit()->setText(QStringLiteral("5.5e-300"));
0502         sb.lineEdit()->setCursorPosition(7);
0503         QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_Down, Qt::KeyboardModifier::NoModifier);
0504         sb.keyPressEvent(&event);
0505         VALUES_EQUAL(sb.value(), 5.5e-307);
0506     }
0507 
0508     {
0509         NumberSpinBox sb;
0510         sb.setLocale(QLocale(QLocale::Language::English));
0511         sb.lineEdit()->setText(QStringLiteral("1.6e-300"));
0512         sb.lineEdit()->setCursorPosition(7);
0513         QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_Down, Qt::KeyboardModifier::NoModifier);
0514         sb.keyPressEvent(&event);
0515         VALUES_EQUAL(sb.value(), 1.6e-308);
0516     }
0517 
0518     {
0519         NumberSpinBox sb;
0520         sb.setLocale(QLocale(QLocale::Language::English));
0521         sb.lineEdit()->setText(QStringLiteral("3.133"));
0522         sb.lineEdit()->setCursorPosition(4);
0523         QKeyEvent downEvent(QKeyEvent::Type::KeyPress, Qt::Key_Down, Qt::KeyboardModifier::NoModifier);
0524         sb.keyPressEvent(&downEvent);
0525         VALUES_EQUAL(sb.value(), 3.123);
0526         sb.keyPressEvent(&downEvent);
0527         VALUES_EQUAL(sb.value(), 3.113);
0528         sb.keyPressEvent(&downEvent);
0529         VALUES_EQUAL(sb.value(), 3.103);
0530         sb.keyPressEvent(&downEvent);
0531         VALUES_EQUAL(sb.value(), 3.093);
0532 
0533         QKeyEvent upEvent(QKeyEvent::Type::KeyPress, Qt::Key_Up, Qt::KeyboardModifier::NoModifier);
0534         sb.keyPressEvent(&upEvent);
0535         VALUES_EQUAL(sb.value(), 3.103);
0536         sb.keyPressEvent(&upEvent);
0537         VALUES_EQUAL(sb.value(), 3.113);
0538 
0539         sb.lineEdit()->setCursorPosition(1);
0540         sb.keyPressEvent(&upEvent);
0541         VALUES_EQUAL(sb.value(), 4.113);
0542 
0543         sb.keyPressEvent(&downEvent);
0544         VALUES_EQUAL(sb.value(), 3.113);
0545     }
0546 
0547     // Even if it crosses an integer it should still lower with the position set
0548     {
0549         NumberSpinBox sb;
0550         sb.setLocale(QLocale(QLocale::Language::English));
0551         sb.lineEdit()->setText(QStringLiteral("4.1"));
0552         sb.lineEdit()->setCursorPosition(4);
0553         QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_Down, Qt::KeyboardModifier::NoModifier);
0554         sb.keyPressEvent(&event);
0555         VALUES_EQUAL(sb.value(), 4.0);
0556         sb.keyPressEvent(&event);
0557         VALUES_EQUAL(sb.value(), 3.9);
0558     }
0559 
0560     {
0561         NumberSpinBox sb;
0562         sb.setLocale(QLocale(QLocale::Language::English));
0563         sb.lineEdit()->setText(QStringLiteral("3.34890823e-03"));
0564         sb.lineEdit()->setCursorPosition(1);
0565         QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_Down, Qt::KeyboardModifier::NoModifier);
0566         sb.keyPressEvent(&event);
0567         VALUES_EQUAL(sb.value(), 2.34890823e-3);
0568         sb.keyPressEvent(&event);
0569         VALUES_EQUAL(sb.value(), 1.34890823e-3);
0570         sb.keyPressEvent(&event);
0571         VALUES_EQUAL(sb.value(), 0.34890823e-3);
0572         sb.keyPressEvent(&event);
0573         VALUES_EQUAL(sb.value(), -1.34890823e-3);
0574 
0575         // e selected do nothing!
0576         sb.lineEdit()->setCursorPosition(12);
0577         sb.keyPressEvent(&event);
0578         VALUES_EQUAL(sb.value(), -1.34890823e-3);
0579 
0580         // Minus selected do nothing!
0581         sb.lineEdit()->setCursorPosition(13);
0582         sb.keyPressEvent(&event);
0583         VALUES_EQUAL(sb.value(), -1.34890823e-3);
0584 
0585         sb.lineEdit()->setCursorPosition(14);
0586         sb.keyPressEvent(&event);
0587         VALUES_EQUAL(sb.value(), -1.34890823e-13);
0588         sb.keyPressEvent(&event);
0589         VALUES_EQUAL(sb.value(), -1.34890823e-23);
0590     }
0591 
0592     // Jump to next valid position with the cursor
0593     // 13 -> 3 -> 2 -> ... (cursor will be automatically set behind the 3)
0594     {
0595         NumberSpinBox sb;
0596         sb.lineEdit()->setText(QStringLiteral("13"));
0597         sb.lineEdit()->setCursorPosition(1);
0598         QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_Down, Qt::KeyboardModifier::NoModifier);
0599         sb.keyPressEvent(&event);
0600         VALUES_EQUAL(sb.value(), 3.);
0601         sb.keyPressEvent(&event);
0602         VALUES_EQUAL(sb.value(), 2.);
0603     }
0604 
0605     // Jump to next valid position with the cursor
0606     // -13 -> -3 -> -2 -> ... (cursor will be automatically set behind the 3)
0607     {
0608         NumberSpinBox sb;
0609         sb.lineEdit()->setText(QStringLiteral("-13"));
0610         sb.lineEdit()->setCursorPosition(2);
0611         QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_Up, Qt::KeyboardModifier::NoModifier);
0612         sb.keyPressEvent(&event);
0613         VALUES_EQUAL(sb.value(), -3.);
0614         sb.keyPressEvent(&event);
0615         VALUES_EQUAL(sb.value(), -2.);
0616     }
0617 }
0618 
0619 void SpinBoxTest::numberSpinBoxLimit() {
0620     NumberSpinBox sb(5);
0621     sb.setMaximum(7);
0622     sb.setMinimum(3);
0623 
0624     int valueChangedCounter = 0;
0625     double lastValue = NAN;
0626     connect(&sb, QOverload<double>::of(&NumberSpinBox::valueChanged), [&valueChangedCounter, &lastValue](double value) {
0627         lastValue = value;
0628         valueChangedCounter++;
0629     });
0630 
0631     sb.lineEdit()->setCursorPosition(1);
0632     sb.increaseValue();
0633     VALUES_EQUAL(sb.value(), 6.);
0634     QCOMPARE(valueChangedCounter, 1);
0635     QCOMPARE(lastValue, 6);
0636     sb.increaseValue();
0637     VALUES_EQUAL(sb.value(), 7.);
0638     QCOMPARE(valueChangedCounter, 2);
0639     QCOMPARE(lastValue, 7);
0640     sb.increaseValue();
0641     VALUES_EQUAL(sb.value(), 7.); // unable to go beyond
0642     QCOMPARE(valueChangedCounter, 2);
0643 
0644     sb.setValue(4);
0645     QCOMPARE(valueChangedCounter, 3);
0646     sb.lineEdit()->setCursorPosition(1);
0647     VALUES_EQUAL(sb.value(), 4.);
0648     QCOMPARE(valueChangedCounter, 3);
0649     sb.decreaseValue();
0650     VALUES_EQUAL(sb.value(), 3.);
0651     QCOMPARE(valueChangedCounter, 4);
0652     QCOMPARE(lastValue, 3);
0653     sb.decreaseValue();
0654     VALUES_EQUAL(sb.value(), 3.);
0655     QCOMPARE(valueChangedCounter, 4);
0656 
0657     // Try to insert a number
0658     sb.lineEdit()->setCursorPosition(1);
0659     // Important: the event text is used by the lineedit. So it has to be filled!
0660     QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_1, Qt::KeyboardModifier::NoModifier, QStringLiteral("1"));
0661     sb.keyPressEvent(&event);
0662     QCOMPARE(valueChangedCounter, 4);
0663     VALUES_EQUAL(sb.value(), 3.);
0664 }
0665 
0666 void SpinBoxTest::numberSpinBoxPrefixSuffix() {
0667     NumberSpinBox sb(5.01);
0668     sb.setMaximum(7);
0669     sb.setMinimum(3);
0670 
0671     int valueChangedCounter = 0;
0672     double lastValue = NAN;
0673     connect(&sb, QOverload<double>::of(&NumberSpinBox::valueChanged), [&valueChangedCounter, &lastValue](double value) {
0674         lastValue = value;
0675         valueChangedCounter++;
0676     });
0677 
0678     sb.setPrefix(QStringLiteral("Prefix "));
0679     sb.setSuffix(QStringLiteral(" Suffix"));
0680 
0681     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("Prefix 5.01 Suffix"));
0682 
0683     sb.lineEdit()->setCursorPosition(14); // In suffix text
0684     QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_Up, Qt::KeyboardModifier::NoModifier);
0685     sb.keyPressEvent(&event);
0686 
0687     QCOMPARE(valueChangedCounter, 1);
0688     QCOMPARE(sb.value(), 5.02);
0689     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("Prefix 5.02 Suffix"));
0690 }
0691 
0692 void SpinBoxTest::numberSpinBoxSuffixFrontToBackSelection() {
0693     // Select from front to back
0694     NumberSpinBox sb;
0695     sb.setSuffix(QStringLiteral(" cm")); // whitespace is important!
0696 
0697     sb.setValue(5);
0698     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("5 cm"));
0699 
0700     int counter = 0;
0701     connect(&sb, QOverload<double>::of(&NumberSpinBox::valueChanged), [&counter](double value) {
0702         QCOMPARE(value, 51);
0703         counter++;
0704     });
0705 
0706     sb.lineEdit()->setSelection(1, 1); // select space
0707     QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_1, Qt::KeyboardModifier::NoModifier, QStringLiteral("1"));
0708     sb.keyPressEvent(&event);
0709 
0710     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("51 cm"));
0711     QCOMPARE(counter, 1);
0712 }
0713 
0714 void SpinBoxTest::numberSpinBoxSuffixBackToFrontSelection() {
0715     // Select from back to front
0716     NumberSpinBox sb;
0717     sb.setSuffix(QStringLiteral(" cm")); // whitespace is important!
0718 
0719     sb.setValue(55);
0720     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("55 cm"));
0721 
0722     int counter = 0;
0723     connect(&sb, QOverload<double>::of(&NumberSpinBox::valueChanged), [&counter](double value) {
0724         QCOMPARE(value, 51);
0725         counter++;
0726     });
0727 
0728     sb.lineEdit()->setSelection(3, -2);
0729     QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_1, Qt::KeyboardModifier::NoModifier, QStringLiteral("1"));
0730     sb.keyPressEvent(&event);
0731 
0732     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("51 cm"));
0733     QCOMPARE(counter, 1);
0734 }
0735 
0736 void SpinBoxTest::numberSpinBoxSuffixSetCursor() {
0737     // Just set cursor into suffix
0738     NumberSpinBox sb;
0739     sb.setSuffix(QStringLiteral(" cm")); // whitespace is important!
0740 
0741     sb.setValue(5);
0742     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("5 cm"));
0743 
0744     int counter = 0;
0745     connect(&sb, QOverload<double>::of(&NumberSpinBox::valueChanged), [&counter](double value) {
0746         QCOMPARE(value, 51);
0747         counter++;
0748     });
0749 
0750     sb.lineEdit()->setCursorPosition(2);
0751     QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_1, Qt::KeyboardModifier::NoModifier, QStringLiteral("1"));
0752     sb.keyPressEvent(&event);
0753 
0754     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("51 cm")); // 1 appended
0755     QCOMPARE(counter, 1);
0756 }
0757 
0758 void SpinBoxTest::numberSpinBoxPrefixFrontToBackSelection() {
0759     // from front to back
0760     NumberSpinBox sb;
0761     sb.setPrefix(QStringLiteral("prefix ")); // whitespace is important!
0762 
0763     sb.setValue(5);
0764     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("prefix 5"));
0765 
0766     sb.lineEdit()->setSelection(1, 7); // ref selected
0767     QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_1, Qt::KeyboardModifier::NoModifier, QStringLiteral("1"));
0768     sb.keyPressEvent(&event);
0769 
0770     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("prefix 1"));
0771 }
0772 
0773 void SpinBoxTest::numberSpinBoxPrefixBackToFrontSelection() {
0774     // from back to front
0775     NumberSpinBox sb;
0776     sb.setPrefix(QStringLiteral("prefix ")); // whitespace is important!
0777 
0778     sb.setValue(5);
0779     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("prefix 5"));
0780 
0781     sb.lineEdit()->setSelection(8, -5); // "fix 5"
0782     QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_1, Qt::KeyboardModifier::NoModifier, QStringLiteral("1"));
0783     sb.keyPressEvent(&event);
0784 
0785     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("prefix 1"));
0786 }
0787 
0788 void SpinBoxTest::numberSpinBoxPrefixSetCursorPosition() {
0789     // set cursor
0790     NumberSpinBox sb;
0791     sb.setPrefix(QStringLiteral("prefix ")); // whitespace is important!
0792 
0793     sb.setValue(5);
0794     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("prefix 5"));
0795 
0796     // For some reason the cursor position is not applied
0797     sb.lineEdit()->setCursorPosition(2);
0798     QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_1, Qt::KeyboardModifier::NoModifier, QStringLiteral("1"));
0799     sb.keyPressEvent(&event);
0800 
0801     // QCOMPARE(sb.lineEdit()->text(), QStringLiteral("prefix 15"));
0802 }
0803 
0804 void SpinBoxTest::numberSpinBoxEnterNumber() {
0805     NumberSpinBox sb;
0806     sb.setDecimals(0);
0807     sb.setValue(5);
0808     sb.setMaximum(100);
0809     sb.setMinimum(0);
0810 
0811     int valueChangedCounter = 0;
0812     double lastValue = NAN;
0813     connect(&sb, QOverload<double>::of(&NumberSpinBox::valueChanged), [&valueChangedCounter, &lastValue](double value) {
0814         lastValue = value;
0815         valueChangedCounter++;
0816     });
0817 
0818     QCOMPARE(sb.toolTip(), QString());
0819     sb.lineEdit()->setCursorPosition(1);
0820     QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_1, Qt::KeyboardModifier::NoModifier, QStringLiteral("1"));
0821     sb.keyPressEvent(&event);
0822     QCOMPARE(sb.toolTip(), QString());
0823     QCOMPARE(sb.value(), 51);
0824     QCOMPARE(valueChangedCounter, 1);
0825 
0826     // 511
0827     sb.keyPressEvent(&event);
0828     QCOMPARE(sb.toolTip(), sb.errorToString(NumberSpinBox::Errors::Max));
0829     QCOMPARE(sb.value(), 51);
0830     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("511"));
0831     QCOMPARE(valueChangedCounter, 1);
0832 
0833     // 51
0834     QKeyEvent event2(QKeyEvent::Type::KeyPress, Qt::Key_Backspace, Qt::KeyboardModifier::NoModifier, QString());
0835     sb.keyPressEvent(&event2);
0836     QCOMPARE(sb.lineEdit()->cursorPosition(), 2);
0837     QCOMPARE(sb.toolTip(), sb.errorToString(NumberSpinBox::Errors::NoError));
0838     QCOMPARE(sb.value(), 51);
0839     QCOMPARE(valueChangedCounter, 1);
0840 
0841     // 5
0842     QKeyEvent event3(QKeyEvent::Type::KeyPress, Qt::Key_Backspace, Qt::KeyboardModifier::NoModifier, QString());
0843     sb.keyPressEvent(&event3);
0844     QCOMPARE(sb.lineEdit()->cursorPosition(), 1);
0845     QCOMPARE(sb.toolTip(), sb.errorToString(NumberSpinBox::Errors::NoError));
0846     QCOMPARE(sb.value(), 5);
0847     QCOMPARE(valueChangedCounter, 2);
0848 
0849     // nothing
0850     QKeyEvent event4(QKeyEvent::Type::KeyPress, Qt::Key_Backspace, Qt::KeyboardModifier::NoModifier, QString());
0851     sb.keyPressEvent(&event4);
0852     QCOMPARE(sb.lineEdit()->cursorPosition(), 0);
0853     QCOMPARE(sb.lineEdit()->text(), QString());
0854     QCOMPARE(sb.toolTip(), sb.errorToString(NumberSpinBox::Errors::NoNumber));
0855     QCOMPARE(sb.value(), 5);
0856     QCOMPARE(valueChangedCounter, 2);
0857 
0858     // -
0859     QKeyEvent event5(QKeyEvent::Type::KeyPress, Qt::Key_Minus, Qt::KeyboardModifier::NoModifier, QStringLiteral("-"));
0860     sb.keyPressEvent(&event5);
0861     QCOMPARE(sb.lineEdit()->cursorPosition(), 1);
0862     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("-"));
0863     QCOMPARE(sb.toolTip(), sb.errorToString(NumberSpinBox::Errors::Invalid));
0864     QCOMPARE(sb.value(), 5);
0865     QCOMPARE(valueChangedCounter, 2);
0866 
0867     // -5
0868     QKeyEvent event6(QKeyEvent::Type::KeyPress, Qt::Key_5, Qt::KeyboardModifier::NoModifier, QStringLiteral("5"));
0869     sb.setMinimum(-100);
0870     sb.keyPressEvent(&event6);
0871     QCOMPARE(sb.lineEdit()->cursorPosition(), 2);
0872     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("-5"));
0873     QCOMPARE(sb.toolTip(), sb.errorToString(NumberSpinBox::Errors::NoError));
0874     QCOMPARE(sb.value(), -5);
0875     QCOMPARE(valueChangedCounter, 3);
0876 
0877     // -5e
0878     QKeyEvent event7(QKeyEvent::Type::KeyPress, Qt::Key_E, Qt::KeyboardModifier::NoModifier, QStringLiteral("e"));
0879     sb.keyPressEvent(&event7);
0880     QCOMPARE(sb.lineEdit()->cursorPosition(), 3);
0881     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("-5e"));
0882     QCOMPARE(sb.toolTip(), sb.errorToString(NumberSpinBox::Errors::Invalid));
0883     QCOMPARE(sb.value(), -5);
0884     QCOMPARE(valueChangedCounter, 3);
0885 
0886     // -5e-
0887     QKeyEvent event8(QKeyEvent::Type::KeyPress, Qt::Key_Minus, Qt::KeyboardModifier::NoModifier, QStringLiteral("-"));
0888     sb.keyPressEvent(&event8);
0889     QCOMPARE(sb.lineEdit()->cursorPosition(), 4);
0890     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("-5e-"));
0891     QCOMPARE(sb.toolTip(), sb.errorToString(NumberSpinBox::Errors::Invalid));
0892     QCOMPARE(sb.value(), -5);
0893     QCOMPARE(valueChangedCounter, 3);
0894 
0895     // -5e-3
0896     QKeyEvent event9(QKeyEvent::Type::KeyPress, Qt::Key_3, Qt::KeyboardModifier::NoModifier, QStringLiteral("3"));
0897     sb.keyPressEvent(&event9);
0898     QCOMPARE(sb.lineEdit()->cursorPosition(), 5);
0899     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("-5e-3"));
0900     QCOMPARE(sb.toolTip(), sb.errorToString(NumberSpinBox::Errors::NoError));
0901     QCOMPARE(sb.value(), -5e-3);
0902     QCOMPARE(valueChangedCounter, 4);
0903 }
0904 
0905 // Testing feedback feature
0906 void SpinBoxTest::numberSpinBoxFeedback() {
0907     NumberSpinBox sb(5);
0908     sb.setFeedback(true);
0909 
0910     int valueChangedCounter = 0;
0911     double lastValue = NAN;
0912     connect(&sb, QOverload<double>::of(&NumberSpinBox::valueChanged), [&sb, &valueChangedCounter, &lastValue](double value) {
0913         lastValue = value;
0914         valueChangedCounter++;
0915 
0916         QCOMPARE(sb.m_waitFeedback, true);
0917         switch (valueChangedCounter) {
0918         case 1:
0919             QCOMPARE(sb.setValue(6), true);
0920             break;
0921         case 2:
0922             QCOMPARE(sb.setValue(0), false);
0923             break;
0924         case 3:
0925             QCOMPARE(sb.setValue(8), true);
0926             break;
0927         }
0928     });
0929 
0930     sb.lineEdit()->setCursorPosition(1);
0931     QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_Up, Qt::KeyboardModifier::NoModifier);
0932 
0933     sb.keyPressEvent(&event);
0934     QCOMPARE(valueChangedCounter, 1);
0935     QCOMPARE(lastValue, 6);
0936     QCOMPARE(sb.toolTip(), sb.errorToString(NumberSpinBox::Errors::NoError));
0937     QCOMPARE(sb.m_waitFeedback, false);
0938 
0939     sb.keyPressEvent(&event);
0940     QCOMPARE(valueChangedCounter, 2);
0941     QCOMPARE(lastValue, 7);
0942     QCOMPARE(sb.toolTip(), QStringLiteral("Invalid value entered. Valid value: %1").arg(0));
0943     QCOMPARE(sb.m_waitFeedback, false);
0944 
0945     sb.keyPressEvent(&event);
0946     QCOMPARE(valueChangedCounter, 3);
0947     QCOMPARE(lastValue, 8);
0948     QCOMPARE(sb.toolTip(), sb.errorToString(NumberSpinBox::Errors::NoError));
0949     QCOMPARE(sb.m_waitFeedback, false);
0950 }
0951 
0952 // set value called directly when valueChanged() is called. This can happen if the other side directly sets another
0953 // value, because the received value is invalid.
0954 void SpinBoxTest::numberSpinBoxFeedback2() {
0955     NumberSpinBox sb(5);
0956     sb.setFeedback(true);
0957 
0958     int valueChangedCounter = 0;
0959     double lastValue = NAN;
0960     connect(&sb, QOverload<double>::of(&NumberSpinBox::valueChanged), [&sb, &valueChangedCounter, &lastValue](double value) {
0961         valueChangedCounter++;
0962         lastValue = value; // value is 6
0963         QVERIFY(5 != value);
0964         sb.setValue(5); // Important other value
0965     });
0966 
0967     sb.lineEdit()->setCursorPosition(1);
0968     QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_Up, Qt::KeyboardModifier::NoModifier);
0969     sb.keyPressEvent(&event);
0970 
0971     QCOMPARE(valueChangedCounter, 1);
0972     QCOMPARE(sb.toolTip(), i18n("Invalid value entered. Valid value: %1", 5));
0973 }
0974 
0975 void SpinBoxTest::numberSpinBoxFeedbackCursorPosition() {
0976     NumberSpinBox sb(5.11);
0977     sb.setFeedback(true);
0978 
0979     int valueChangedCounter = 0;
0980     // double lastValue = NAN;
0981     connect(&sb, QOverload<double>::of(&NumberSpinBox::valueChanged), [&sb, &valueChangedCounter](double value) {
0982         valueChangedCounter++;
0983         sb.setValue(value);
0984     });
0985 
0986     sb.lineEdit()->setCursorPosition(3); // after first 1
0987     QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_Up, Qt::KeyboardModifier::NoModifier);
0988     sb.keyPressEvent(&event);
0989 
0990     QCOMPARE(valueChangedCounter, 1);
0991     QCOMPARE(sb.lineEdit()->cursorPosition(), 3);
0992     QCOMPARE(sb.value(), 5.21);
0993     QCOMPARE(sb.toolTip(), QStringLiteral(""));
0994 
0995     // another time key up
0996     sb.keyPressEvent(&event);
0997 
0998     QCOMPARE(valueChangedCounter, 2);
0999     QCOMPARE(sb.lineEdit()->cursorPosition(), 3);
1000     QCOMPARE(sb.value(), 5.31);
1001     QCOMPARE(sb.toolTip(), QStringLiteral(""));
1002 }
1003 
1004 void SpinBoxTest::numberSpinBoxFeedbackCursorPosition2() {
1005     Project project;
1006     auto* ws = new Worksheet(QStringLiteral("worksheet"));
1007     QVERIFY(ws != nullptr);
1008     project.addChild(ws);
1009 
1010     auto* p = new CartesianPlot(QStringLiteral("plot"));
1011     p->setType(CartesianPlot::Type::TwoAxes); // Otherwise no axis are created
1012     QVERIFY(p != nullptr);
1013     ws->addChild(p);
1014 
1015     auto* curve{new XYEquationCurve(QStringLiteral("f(x)"))};
1016     curve->setCoordinateSystemIndex(p->defaultCoordinateSystemIndex());
1017     p->addChild(curve);
1018 
1019     XYEquationCurve::EquationData data;
1020     data.min = QStringLiteral("1");
1021     data.max = QStringLiteral("2");
1022     data.count = 1000;
1023     data.expression1 = QStringLiteral("x");
1024     curve->setEquationData(data);
1025     curve->recalculate();
1026 
1027     CHECK_RANGE(p, curve, Dimension::X, 1.0, 2.0);
1028     CHECK_RANGE(p, curve, Dimension::Y, 1.0, 2.0);
1029 
1030     CartesianPlotDock d(nullptr);
1031 
1032     d.setPlots({p});
1033     d.setPlots({p}); // Important to do it a second time to see that the connections are cleared bevore connecting again
1034 
1035     QCOMPARE(d.ui.sbPaddingHorizontal->lineEdit()->text(), QStringLiteral("1.5 cm"));
1036     d.ui.sbPaddingHorizontal->lineEdit()->setCursorPosition(3);
1037 
1038     QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_Up, Qt::KeyboardModifier::NoModifier);
1039     d.ui.sbPaddingHorizontal->keyPressEvent(&event);
1040 
1041     QCOMPARE(d.ui.sbPaddingHorizontal->lineEdit()->text(), QStringLiteral("1.6 cm"));
1042     QCOMPARE(d.ui.sbPaddingHorizontal->lineEdit()->cursorPosition(), 3);
1043 }
1044 
1045 // \brief SpinBoxTest::numberSpinBoxDecimals
1046 // Check that application shows the correct value, even decimals is set to zero
1047 void SpinBoxTest::numberSpinBoxDecimals2() {
1048     NumberSpinBox sb;
1049     sb.setMinimum(-10);
1050     sb.setDecimals(0);
1051     sb.setValue(-1);
1052     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("-1"));
1053 }
1054 
1055 void SpinBoxTest::numberSpinBoxScrollingNegToPos() {
1056     NumberSpinBox sb;
1057     sb.setMinimum(-10);
1058     sb.setValue(-1.01);
1059     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("-1.01"));
1060 
1061     sb.lineEdit()->setCursorPosition(2);
1062     QKeyEvent upEvent(QKeyEvent::Type::KeyPress, Qt::Key_Up, Qt::KeyboardModifier::NoModifier);
1063     sb.keyPressEvent(&upEvent);
1064 
1065     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("-0.01"));
1066     QCOMPARE(sb.lineEdit()->cursorPosition(), 2); // cursor should not be at position of the comma but behind the 0
1067 
1068     QKeyEvent downEvent(QKeyEvent::Type::KeyPress, Qt::Key_Down, Qt::KeyboardModifier::NoModifier);
1069     sb.keyPressEvent(&downEvent);
1070 
1071     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("-1.01"));
1072     QCOMPARE(sb.lineEdit()->cursorPosition(), 2); // cursor should not be at position of the minus but behind the 1
1073 }
1074 
1075 void SpinBoxTest::numberSpinBoxScrollingNegToPos2() {
1076     NumberSpinBox sb;
1077     sb.setMinimum(-10);
1078     sb.setValue(0.13);
1079     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("0.13"));
1080 
1081     sb.lineEdit()->setCursorPosition(1);
1082     QKeyEvent downEvent(QKeyEvent::Type::KeyPress, Qt::Key_Down, Qt::KeyboardModifier::NoModifier);
1083     sb.keyPressEvent(&downEvent);
1084 
1085     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("-1.13")); // The first number should change not (0.13-1 = -0.87)
1086     QCOMPARE(sb.lineEdit()->cursorPosition(), 2);
1087 
1088     QKeyEvent upEvent(QKeyEvent::Type::KeyPress, Qt::Key_Up, Qt::KeyboardModifier::NoModifier);
1089     sb.keyPressEvent(&upEvent);
1090 
1091     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("-0.13"));
1092     QCOMPARE(sb.lineEdit()->cursorPosition(), 2);
1093 
1094     sb.keyPressEvent(&upEvent);
1095 
1096     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("1.13"));
1097     QCOMPARE(sb.lineEdit()->cursorPosition(), 1);
1098 }
1099 
1100 void SpinBoxTest::numberSpinBoxScrollingNegativeValues() {
1101     NumberSpinBox sb;
1102     sb.setMinimum(-20);
1103     sb.setValue(-9.81);
1104     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("-9.81"));
1105 
1106     sb.lineEdit()->setCursorPosition(2);
1107     QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_Down, Qt::KeyboardModifier::NoModifier);
1108     sb.keyPressEvent(&event);
1109 
1110     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("-10.81"));
1111     QCOMPARE(sb.lineEdit()->cursorPosition(), 3);
1112 
1113     sb.keyPressEvent(&event);
1114 
1115     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("-11.81"));
1116     QCOMPARE(sb.lineEdit()->cursorPosition(), 3);
1117 }
1118 
1119 void SpinBoxTest::numberSpinBoxMinimumFeedback() {
1120     // Limit to min/max when stepping in the spinbox
1121     // instead of raising an error
1122     NumberSpinBox sb;
1123     sb.setMinimum(0);
1124     sb.setValue(1.01);
1125     sb.setFeedback(true);
1126 
1127     int valueChangedCounter = 0;
1128     double lastValue = NAN;
1129     connect(&sb, QOverload<double>::of(&NumberSpinBox::valueChanged), [&valueChangedCounter, &lastValue](double value) {
1130         valueChangedCounter++;
1131         lastValue = value;
1132     });
1133 
1134     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("1.01"));
1135 
1136     sb.lineEdit()->setCursorPosition(1);
1137     QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_Down, Qt::KeyboardModifier::NoModifier);
1138     sb.keyPressEvent(&event);
1139 
1140     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("0.01"));
1141     QCOMPARE(sb.lineEdit()->cursorPosition(), 1);
1142     QCOMPARE(valueChangedCounter, 1);
1143     QCOMPARE(sb.toolTip(), QString());
1144 
1145     sb.keyPressEvent(&event);
1146     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("0.01"));
1147     QCOMPARE(sb.lineEdit()->cursorPosition(), 1);
1148     QCOMPARE(valueChangedCounter, 1);
1149     QCOMPARE(sb.toolTip(), QString());
1150 
1151     sb.lineEdit()->setCursorPosition(4);
1152     sb.keyPressEvent(&event);
1153     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("0.00"));
1154     QCOMPARE(sb.lineEdit()->cursorPosition(), 4);
1155     QCOMPARE(valueChangedCounter, 2);
1156     QCOMPARE(sb.toolTip(), QString());
1157 
1158     sb.keyPressEvent(&event);
1159     QCOMPARE(sb.lineEdit()->text(), QStringLiteral("0.00"));
1160     QCOMPARE(sb.lineEdit()->cursorPosition(), 4);
1161     QCOMPARE(valueChangedCounter, 2);
1162     QCOMPARE(sb.toolTip(), QString());
1163 }
1164 
1165 // \brief SpinBoxTest::numberSpinBoxDecimalsMinMax
1166 // In the default implementation of QDoubleSpinbox the maximum and
1167 // minimums are round to the decimals. The numberspinbox should not do
1168 // this
1169 void SpinBoxTest::numberSpinBoxDecimalsMinMax() {
1170     NumberSpinBox sb;
1171     sb.setDecimals(2);
1172     sb.setMaximum(1.289343892e-10);
1173     QCOMPARE(sb.maximum(), 1.289343892e-10); // not rounded!
1174 
1175     sb.setMinimum(1.289343892e-15);
1176     QCOMPARE(sb.minimum(), 1.289343892e-15); // not rounded!
1177 }
1178 
1179 void SpinBoxTest::thousandSeparator() {
1180     {
1181         NumberSpinBox sb;
1182         sb.setLocale(QLocale(QLocale::German));
1183         QCOMPARE(sb.locale().decimalPoint(), QLatin1Char(','));
1184         QCOMPARE(sb.locale().groupSeparator(), QLatin1Char('.'));
1185 
1186         sb.setValue(50000);
1187         QCOMPARE(sb.text(), QStringLiteral("50.000"));
1188 
1189         sb.lineEdit()->setCursorPosition(0);
1190         QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_1, Qt::KeyboardModifier::NoModifier, QStringLiteral("1"));
1191         sb.keyPressEvent(&event);
1192 
1193         QCOMPARE(sb.value(), 150000);
1194         QCOMPARE(sb.text(), QStringLiteral("150.000"));
1195     }
1196 }
1197 
1198 void SpinBoxTest::thousandSeparatorNegative() {
1199     NumberSpinBox sb;
1200     sb.setLocale(QLocale(QLocale::German));
1201     QCOMPARE(sb.locale().decimalPoint(), QLatin1Char(','));
1202     QCOMPARE(sb.locale().groupSeparator(), QLatin1Char('.'));
1203 
1204     sb.setValue(-50000.1);
1205     QCOMPARE(sb.text(), QStringLiteral("-50.000,1"));
1206 
1207     sb.lineEdit()->setCursorPosition(0);
1208     QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_Delete, Qt::KeyboardModifier::NoModifier);
1209     sb.keyPressEvent(&event);
1210 
1211     QCOMPARE(sb.value(), 50000.1);
1212     QCOMPARE(sb.text(), QStringLiteral("50.000,1"));
1213 }
1214 
1215 void SpinBoxTest::thousandSeparatorScrolling() {
1216     NumberSpinBox sb;
1217     sb.setLocale(QLocale(QLocale::German));
1218     QCOMPARE(sb.locale().decimalPoint(), QLatin1Char(','));
1219     QCOMPARE(sb.locale().groupSeparator(), QLatin1Char('.'));
1220 
1221     sb.setValue(90000.1);
1222     QCOMPARE(sb.text(), QStringLiteral("90.000,1"));
1223 
1224     sb.lineEdit()->setCursorPosition(1);
1225     QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_Up, Qt::KeyboardModifier::NoModifier);
1226     sb.keyPressEvent(&event);
1227 
1228     QCOMPARE(sb.value(), 100000.1);
1229     QCOMPARE(sb.text(), QStringLiteral("100.000,1"));
1230 }
1231 
1232 void SpinBoxTest::thousandSeparatorScrolling2() {
1233     NumberSpinBox sb;
1234     sb.setLocale(QLocale(QLocale::German));
1235     QCOMPARE(sb.locale().decimalPoint(), QLatin1Char(','));
1236     QCOMPARE(sb.locale().groupSeparator(), QLatin1Char('.'));
1237 
1238     sb.setValue(24000.1);
1239     QCOMPARE(sb.text(), QStringLiteral("24.000,1"));
1240 
1241     sb.lineEdit()->setCursorPosition(2);
1242     QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_Up, Qt::KeyboardModifier::NoModifier);
1243     sb.keyPressEvent(&event);
1244 
1245     QCOMPARE(sb.value(), 25000.1);
1246     QCOMPARE(sb.text(), QStringLiteral("25.000,1"));
1247 }
1248 
1249 void SpinBoxTest::thousandSeparatorScrollingSeparatorPosition() {
1250     QSKIP("Undecided what to do");
1251     NumberSpinBox sb;
1252     sb.setLocale(QLocale(QLocale::German));
1253     QCOMPARE(sb.locale().decimalPoint(), QLatin1Char(','));
1254     QCOMPARE(sb.locale().groupSeparator(), QLatin1Char('.'));
1255 
1256     sb.setValue(50000);
1257     QCOMPARE(sb.text(), QStringLiteral("50.000"));
1258 
1259     sb.lineEdit()->setCursorPosition(3);
1260     QKeyEvent event(QKeyEvent::Type::KeyPress, Qt::Key_Up, Qt::KeyboardModifier::NoModifier);
1261     sb.keyPressEvent(&event);
1262 
1263     QCOMPARE(sb.value(), 50000);
1264     QCOMPARE(sb.text(), QStringLiteral("50.000"));
1265 }
1266 
1267 QTEST_MAIN(SpinBoxTest)