466 lines
21 KiB
C++
466 lines
21 KiB
C++
#include "UI/NewCanvasSheet.h"
|
||
#include <QBuffer>
|
||
#include <QClipboard>
|
||
#include <QImageReader>
|
||
#include <QImageWriter>
|
||
#include <QMenu>
|
||
#include <QtTest>
|
||
|
||
// The welcome sheet: sizes, its three ways on, the clipboard.
|
||
namespace {
|
||
struct Sheet {
|
||
EditorSession session;
|
||
QList<QSize> created;
|
||
QList<double> resolutions;
|
||
QList<std::optional<QColor>> backgrounds;
|
||
int opened = 0;
|
||
NewCanvasSheet sheet{session,
|
||
[this](int width, int height, double resolution, std::optional<QColor> background) {
|
||
created << QSize(width, height);
|
||
resolutions << resolution;
|
||
backgrounds << background;
|
||
},
|
||
[this] { opened += 1; }};
|
||
QLineEdit &width = *sheet.findChild<QLineEdit *>("widthInput");
|
||
QLineEdit &height = *sheet.findChild<QLineEdit *>("heightInput");
|
||
QLabel ¬e = *sheet.findChild<QLabel *>("canvasNote");
|
||
QPushButton &create = *sheet.findChild<QPushButton *>("createCanvas");
|
||
QToolButton &presets = *sheet.findChild<QToolButton *>("presetSizes");
|
||
|
||
// The menu's entries, a separator as "-".
|
||
QStringList entries() const
|
||
{
|
||
QStringList titles;
|
||
for (const QAction *action : presets.menu()->actions())
|
||
titles << (action->isSeparator() ? QStringLiteral("-") : action->text());
|
||
return titles;
|
||
}
|
||
QString checked() const
|
||
{
|
||
QStringList titles;
|
||
for (const QAction *action : presets.menu()->actions())
|
||
if (action->isChecked())
|
||
titles << action->text();
|
||
return titles.join(',');
|
||
}
|
||
QAction &entry(const QString &title) const
|
||
{
|
||
for (QAction *action : presets.menu()->actions())
|
||
if (action->text() == title)
|
||
return *action;
|
||
throw std::runtime_error("no such preset");
|
||
}
|
||
};
|
||
|
||
QByteArray encoded(const QImage &image, const char *format, QImageIOHandler::Transformations turned = QImageIOHandler::TransformationNone)
|
||
{
|
||
QByteArray bytes;
|
||
QBuffer buffer(&bytes);
|
||
QImageWriter writer(&buffer, format);
|
||
writer.setTransformation(turned);
|
||
if (!writer.write(image))
|
||
throw std::runtime_error("the fixture could not be encoded");
|
||
return bytes;
|
||
}
|
||
}
|
||
|
||
class NewCanvasSheetTests : public QObject {
|
||
Q_OBJECT
|
||
private slots:
|
||
void cleanup();
|
||
void itStartsAtFullHighDefinition();
|
||
void onlyWholeNumbersInRangeMayCreate();
|
||
void returnInEitherFieldCreates();
|
||
void theOtherTwoButtonsOpenAndImport();
|
||
void itGivesWayWhileTheSessionWorks();
|
||
void aCopiedPicturesSizeIsSuggestedOnce();
|
||
void theFirstTabSkipsTheClipboardOnce();
|
||
void clipboardSizesComeFromHeadersAlone();
|
||
void presetsAreSwiftsGroups();
|
||
void aPresetFillsTheFieldsAndTheMatchIsChecked();
|
||
void theMoreButtonDrawsThreeDotsAndOpensTheMenu();
|
||
void thePillsStepThroughTheirChoices();
|
||
void printUnitsWriteTheSameCanvas();
|
||
};
|
||
|
||
void NewCanvasSheetTests::cleanup()
|
||
{
|
||
QApplication::clipboard()->clear();
|
||
}
|
||
|
||
void NewCanvasSheetTests::itStartsAtFullHighDefinition()
|
||
{
|
||
Sheet fixture;
|
||
fixture.sheet.show();
|
||
QVERIFY(QTest::qWaitForWindowExposed(&fixture.sheet));
|
||
QCOMPARE(fixture.width.text(), QString("1920"));
|
||
QCOMPARE(fixture.height.text(), QString("1080"));
|
||
QVERIFY(fixture.note.isHidden());
|
||
QVERIFY(fixture.create.isEnabled() && fixture.create.isDefault() && fixture.width.hasFocus());
|
||
QCOMPARE(fixture.sheet.width(), 500);
|
||
QTest::mouseClick(&fixture.create, Qt::LeftButton);
|
||
QCOMPARE(fixture.created, (QList<QSize>{QSize(1920, 1080)}));
|
||
QCOMPARE(fixture.resolutions, QList<double>{72});
|
||
QCOMPARE(fixture.backgrounds, QList<std::optional<QColor>>{std::nullopt});
|
||
}
|
||
|
||
void NewCanvasSheetTests::onlyWholeNumbersInRangeMayCreate()
|
||
{
|
||
Sheet fixture;
|
||
// Shown and active, so that Return reaches the sheet.
|
||
fixture.sheet.show();
|
||
fixture.sheet.activateWindow();
|
||
QVERIFY(QTest::qWaitForWindowActive(&fixture.sheet));
|
||
const auto valid = [&](const QString &width, const QString &height) {
|
||
fixture.width.setText(width);
|
||
fixture.height.setText(height);
|
||
return fixture.create.isEnabled();
|
||
};
|
||
QVERIFY(valid("1", "30000"));
|
||
QVERIFY(valid("30000", "1"));
|
||
QVERIFY(valid(" 640 ", "480"));
|
||
// Either field alone refuses, by button, Return and Enter.
|
||
const auto refused = [&] {
|
||
const bool warned = fixture.note.text() == "Enter whole numbers from 1 to 30,000 pixels." && fixture.note.foregroundRole() == QPalette::BrightText
|
||
&& !fixture.note.isHidden();
|
||
fixture.create.click();
|
||
QTest::keyClick(&fixture.width, Qt::Key_Return);
|
||
QTest::keyClick(&fixture.height, Qt::Key_Enter);
|
||
fixture.sheet.findChild<QPushButton *>("openProject")->setFocus();
|
||
QTest::keyClick(&fixture.sheet, Qt::Key_Return);
|
||
return warned && fixture.created.isEmpty();
|
||
};
|
||
// Swift's Double(text): whole numbers written any way pass.
|
||
QVERIFY(valid("1e3", "480.0") && valid("6,4e2", "480"));
|
||
for (const QString &bad : {QString("0"), QString("30001"), QString(""), QString("12.5"), QString("-4"), QString("3e4.5"), QString("wide"),
|
||
QString("inf"), QString("nan"), QString("\n640"), QString("640\n")}) {
|
||
QVERIFY2(!valid(bad, "480") && refused(), qPrintable(bad));
|
||
QVERIFY2(!valid("640", bad) && refused(), qPrintable(bad));
|
||
}
|
||
QVERIFY(fixture.created.isEmpty() && fixture.opened == 0);
|
||
QVERIFY(valid("640", "480"));
|
||
QVERIFY(fixture.note.isHidden());
|
||
}
|
||
|
||
void NewCanvasSheetTests::returnInEitherFieldCreates()
|
||
{
|
||
Sheet fixture;
|
||
fixture.sheet.show();
|
||
QVERIFY(QTest::qWaitForWindowExposed(&fixture.sheet));
|
||
fixture.width.setText("300");
|
||
fixture.height.setText(" 200");
|
||
QTest::keyClick(&fixture.width, Qt::Key_Return);
|
||
QTest::keyClick(&fixture.height, Qt::Key_Return);
|
||
QCOMPARE(fixture.created, (QList<QSize>{QSize(300, 200), QSize(300, 200)}));
|
||
// Return with a button in focus creates as well.
|
||
fixture.sheet.activateWindow();
|
||
QVERIFY(QTest::qWaitForWindowActive(&fixture.sheet));
|
||
fixture.sheet.findChild<QPushButton *>("openProject")->setFocus();
|
||
QTest::keyClick(&fixture.sheet, Qt::Key_Return);
|
||
fixture.sheet.findChild<QPushButton *>("importImage")->setFocus();
|
||
QTest::keyClick(&fixture.sheet, Qt::Key_Enter);
|
||
QCOMPARE(fixture.created.size(), 4);
|
||
QCOMPARE(fixture.opened, 0);
|
||
QVERIFY(!fixture.session.showsImporter());
|
||
}
|
||
|
||
void NewCanvasSheetTests::theOtherTwoButtonsOpenAndImport()
|
||
{
|
||
Sheet fixture;
|
||
QSignalSpy changes(&fixture.session, &EditorSession::changed);
|
||
fixture.sheet.findChild<QPushButton *>("openProject")->click();
|
||
QCOMPARE(fixture.opened, 1);
|
||
QCOMPARE(changes.count(), 0);
|
||
QVERIFY(!fixture.session.showsImporter());
|
||
fixture.sheet.findChild<QPushButton *>("importImage")->click();
|
||
QVERIFY(fixture.session.showsImporter());
|
||
QVERIFY(fixture.created.isEmpty() && fixture.opened == 1);
|
||
}
|
||
|
||
void NewCanvasSheetTests::itGivesWayWhileTheSessionWorks()
|
||
{
|
||
Sheet fixture;
|
||
QVERIFY(fixture.sheet.isEnabled());
|
||
fixture.session.setIsImporting(true);
|
||
QVERIFY(!fixture.sheet.isEnabled());
|
||
fixture.session.setIsImporting(false);
|
||
QVERIFY(fixture.sheet.isEnabled());
|
||
// Busy dims only once it shows, a quarter second in.
|
||
fixture.session.setIsProjectBusy(true);
|
||
QVERIFY(fixture.sheet.isEnabled());
|
||
QTRY_VERIFY(!fixture.sheet.isEnabled());
|
||
fixture.session.setIsProjectBusy(false);
|
||
QVERIFY(fixture.sheet.isEnabled());
|
||
}
|
||
|
||
void NewCanvasSheetTests::aCopiedPicturesSizeIsSuggestedOnce()
|
||
{
|
||
auto *copied = new QMimeData;
|
||
copied->setData("image/png", encoded(QImage(640, 360, QImage::Format_RGBA8888), "png"));
|
||
QApplication::clipboard()->setMimeData(copied);
|
||
Sheet fixture;
|
||
QCOMPARE(fixture.width.text(), QString("1920"));
|
||
fixture.sheet.show();
|
||
QVERIFY(QTest::qWaitForWindowExposed(&fixture.sheet));
|
||
QCOMPARE(fixture.width.text(), QString("640"));
|
||
QCOMPARE(fixture.height.text(), QString("360"));
|
||
// Shown again, it keeps what the user has typed since.
|
||
fixture.width.setText("111");
|
||
fixture.height.setFocus();
|
||
fixture.sheet.hide();
|
||
fixture.sheet.show();
|
||
QCOMPARE(fixture.width.text(), QString("111"));
|
||
// Shown again, the width is the field to type in.
|
||
QCOMPARE(fixture.sheet.focusWidget(), &fixture.width);
|
||
}
|
||
|
||
void NewCanvasSheetTests::theFirstTabSkipsTheClipboardOnce()
|
||
{
|
||
auto *copied = new QMimeData;
|
||
copied->setData("image/png", encoded(QImage(640, 360, QImage::Format_RGBA8888), "png"));
|
||
QApplication::clipboard()->setMimeData(copied);
|
||
Sheet first;
|
||
first.session.skipsInitialClipboardCanvasSize = true;
|
||
first.sheet.show();
|
||
QVERIFY(QTest::qWaitForWindowExposed(&first.sheet));
|
||
QCOMPARE(first.width.text(), QString("1920"));
|
||
QVERIFY(!first.session.skipsInitialClipboardCanvasSize);
|
||
// The session's next sheet reads the clipboard again.
|
||
NewCanvasSheet later(first.session, [](int, int, double, std::optional<QColor>) {}, [] {});
|
||
later.show();
|
||
QVERIFY(QTest::qWaitForWindowExposed(&later));
|
||
QCOMPARE(later.findChild<QLineEdit *>("widthInput")->text(), QString("640"));
|
||
}
|
||
|
||
void NewCanvasSheetTests::clipboardSizesComeFromHeadersAlone()
|
||
{
|
||
QVERIFY(!NewCanvasSheet::clipboardDimensions(nullptr).has_value());
|
||
QMimeData clipboard;
|
||
QVERIFY(!NewCanvasSheet::clipboardDimensions(&clipboard).has_value());
|
||
clipboard.setText("640 x 360");
|
||
QVERIFY(!NewCanvasSheet::clipboardDimensions(&clipboard).has_value());
|
||
// A tall TIFF; a PNG beside it comes first.
|
||
clipboard.setData("image/tiff", encoded(QImage(30, 50, QImage::Format_RGBA8888), "tiff"));
|
||
QCOMPARE(NewCanvasSheet::clipboardDimensions(&clipboard), std::optional(QSize(30, 50)));
|
||
clipboard.setData("image/png", encoded(QImage(70, 20, QImage::Format_RGBA8888), "png"));
|
||
QCOMPARE(NewCanvasSheet::clipboardDimensions(&clipboard), std::optional(QSize(70, 20)));
|
||
// No pixel is decoded: past Qt's limit it still counts.
|
||
const int limit = QImageReader::allocationLimit();
|
||
QImageReader::setAllocationLimit(1);
|
||
QMimeData large;
|
||
large.setData("image/png", encoded(QImage(2000, 1000, QImage::Format_RGBA8888), "png"));
|
||
const std::optional<QSize> measured = NewCanvasSheet::clipboardDimensions(&large);
|
||
QImageReader::setAllocationLimit(limit);
|
||
QCOMPARE(measured, std::optional(QSize(2000, 1000)));
|
||
// Too large for a canvas: the next type is tried.
|
||
QMimeData vast;
|
||
vast.setData("image/png", encoded(QImage(30001, 1, QImage::Format_Grayscale8), "png"));
|
||
QVERIFY(!NewCanvasSheet::clipboardDimensions(&vast).has_value());
|
||
vast.setData("image/tiff", encoded(QImage(30, 50, QImage::Format_RGBA8888), "tiff"));
|
||
QCOMPARE(NewCanvasSheet::clipboardDimensions(&vast), std::optional(QSize(30, 50)));
|
||
QMimeData broken;
|
||
broken.setData("image/png", "not a picture");
|
||
QVERIFY(!NewCanvasSheet::clipboardDimensions(&broken).has_value());
|
||
// Too tall as well as too wide is refused.
|
||
QMimeData tall;
|
||
tall.setData("image/png", encoded(QImage(1, 30001, QImage::Format_Grayscale8), "png"));
|
||
QVERIFY(!NewCanvasSheet::clipboardDimensions(&tall).has_value());
|
||
// A TIFF stored on its side swaps its sides.
|
||
QMimeData turned;
|
||
turned.setData("image/tiff", encoded(QImage(30, 50, QImage::Format_RGBA8888), "tiff", QImageIOHandler::TransformationRotate90));
|
||
QCOMPARE(NewCanvasSheet::clipboardDimensions(&turned), std::optional(QSize(50, 30)));
|
||
}
|
||
|
||
void NewCanvasSheetTests::presetsAreSwiftsGroups()
|
||
{
|
||
QStringList sizes;
|
||
for (const std::vector<CanvasPreset> &group : CanvasPreset::groups) {
|
||
for (const CanvasPreset &preset : group)
|
||
sizes << QStringLiteral("%1 %2x%3").arg(preset.title).arg(preset.width).arg(preset.height);
|
||
sizes << "-";
|
||
}
|
||
QCOMPARE(sizes, (QStringList{"4K 3840x2160", "1440p 2560x1440", "1080p 1920x1080", "-", "iPhone 18 Pro 1206x2622", "iPhone 18 Pro Max 1320x2868",
|
||
"MacBook Pro 14\" 3024x1964", "MacBook Pro 16\" 3456x2234", "Studio Display 5120x2880", "-", "Instagram Square 1080x1080",
|
||
"Instagram Portrait 1080x1350", "Instagram Story 1080x1920", "YouTube Thumb 1080x608", "-"}));
|
||
QCOMPARE(CanvasPreset::all.size(), size_t(12));
|
||
QCOMPARE(CanvasPreset::all.back().title, QString("YouTube Thumb"));
|
||
Sheet fixture;
|
||
QCOMPARE(fixture.entries(), (QStringList{"Custom", "-", "4K", "1440p", "1080p", "-", "iPhone 18 Pro", "iPhone 18 Pro Max", "MacBook Pro 14\"",
|
||
"MacBook Pro 16\"", "Studio Display", "-", "Instagram Square", "Instagram Portrait", "Instagram Story",
|
||
"YouTube Thumb"}));
|
||
QCOMPARE(fixture.presets.toolTip(), QString("Preset sizes for screens and common formats"));
|
||
QCOMPARE(fixture.presets.accessibleName(), QString("Preset sizes"));
|
||
QCOMPARE(fixture.presets.size(), QSize(28, 28));
|
||
QCOMPARE(fixture.presets.popupMode(), QToolButton::InstantPopup);
|
||
}
|
||
|
||
void NewCanvasSheetTests::aPresetFillsTheFieldsAndTheMatchIsChecked()
|
||
{
|
||
Sheet fixture;
|
||
QCOMPARE(fixture.checked(), QString("1080p"));
|
||
fixture.entry("Instagram Story").trigger();
|
||
QCOMPARE(fixture.width.text(), QString("1080"));
|
||
QCOMPARE(fixture.height.text(), QString("1920"));
|
||
QCOMPARE(fixture.checked(), QString("Instagram Story"));
|
||
fixture.entry("Studio Display").trigger();
|
||
QCOMPARE(fixture.width.text() + "x" + fixture.height.text(), QString("5120x2880"));
|
||
QCOMPARE(fixture.checked(), QString("Studio Display"));
|
||
// No preset has it: Custom. Presets match by pixels.
|
||
fixture.height.setText("2881");
|
||
QCOMPARE(fixture.checked(), QString("Custom"));
|
||
fixture.height.setText("2880");
|
||
QCOMPARE(fixture.checked(), QString("Studio Display"));
|
||
fixture.width.setText("05120.0");
|
||
QCOMPARE(fixture.checked(), QString("Studio Display"));
|
||
fixture.width.setText("5121");
|
||
QCOMPARE(fixture.checked(), QString("Custom"));
|
||
fixture.width.setText("1080");
|
||
fixture.height.setText("608");
|
||
QCOMPARE(fixture.checked(), QString("YouTube Thumb"));
|
||
// Custom fills nothing in.
|
||
fixture.entry("Custom").trigger();
|
||
QCOMPARE(fixture.width.text() + "x" + fixture.height.text(), QString("1080x608"));
|
||
QCOMPARE(fixture.checked(), QString("YouTube Thumb"));
|
||
fixture.entry("4K").trigger();
|
||
QCOMPARE(fixture.checked(), QString("4K"));
|
||
QVERIFY(fixture.create.isEnabled());
|
||
QTest::mouseClick(&fixture.create, Qt::LeftButton);
|
||
QCOMPARE(fixture.created, (QList<QSize>{QSize(3840, 2160)}));
|
||
}
|
||
|
||
void NewCanvasSheetTests::theMoreButtonDrawsThreeDotsAndOpensTheMenu()
|
||
{
|
||
Sheet fixture;
|
||
fixture.sheet.show();
|
||
QVERIFY(QTest::qWaitForWindowExposed(&fixture.sheet));
|
||
// Flush with the content's right edge, 28 points in.
|
||
QCOMPARE(fixture.presets.geometry().right() + 1, 500 - 28);
|
||
const QImage image = fixture.presets.grab().toImage();
|
||
const QColor ground = image.pixelColor(2, 2), ink = fixture.presets.palette().color(QPalette::WindowText);
|
||
// Dots centred at x 26.75, y 9, 14 and 19.
|
||
for (const int y : {9, 14, 19})
|
||
QVERIFY2(std::abs(qGray(image.pixel(26, y)) - qGray(ink.rgb())) < std::abs(qGray(image.pixel(26, y)) - qGray(ground.rgb())), qPrintable(QString::number(y)));
|
||
for (const QPoint clear : {QPoint(26, 11), QPoint(26, 16), QPoint(26, 5), QPoint(26, 23), QPoint(22, 14), QPoint(14, 14)})
|
||
QCOMPARE(image.pixelColor(clear), ground);
|
||
// Filled, never outlined: a red ink stays red.
|
||
QPalette red = fixture.presets.palette();
|
||
red.setColor(QPalette::WindowText, Qt::red);
|
||
fixture.presets.setPalette(red);
|
||
const QColor centre = fixture.presets.grab().toImage().pixelColor(26, 14);
|
||
QVERIFY2(centre.red() > 200 && centre.red() - centre.green() > 60, qPrintable(centre.name()));
|
||
// Qt 6.12 shows the menu later: watch until it shows.
|
||
bool shown = false;
|
||
QTimer watch;
|
||
QObject::connect(&watch, &QTimer::timeout, [&] {
|
||
if (!fixture.presets.menu()->isVisible())
|
||
return;
|
||
shown = true;
|
||
fixture.presets.menu()->close();
|
||
});
|
||
watch.start(10);
|
||
QTest::mouseClick(&fixture.presets, Qt::LeftButton);
|
||
QTRY_VERIFY(shown);
|
||
}
|
||
|
||
void NewCanvasSheetTests::thePillsStepThroughTheirChoices()
|
||
{
|
||
Sheet fixture;
|
||
fixture.sheet.show();
|
||
QVERIFY(QTest::qWaitForWindowExposed(&fixture.sheet));
|
||
QAbstractButton &background = *fixture.sheet.findChild<QAbstractButton *>("canvasBackground");
|
||
QAbstractButton &unit = *fixture.sheet.findChild<QAbstractButton *>("canvasUnit");
|
||
QAbstractButton &resolution = *fixture.sheet.findChild<QAbstractButton *>("canvasResolution");
|
||
QCOMPARE(background.text(), QString("Transparent canvas"));
|
||
QCOMPARE(unit.text(), QString("Pixels"));
|
||
QCOMPARE(resolution.text(), QString("72 DPI"));
|
||
QCOMPARE(background.toolTip(), QString("Start see-through, or with a white or black Background layer. Click to switch."));
|
||
QCOMPARE(unit.toolTip(), QString("Units: pixels, inches, centimeters or millimeters. Click to switch."));
|
||
QCOMPARE(resolution.toolTip(), QString("Resolution: 72 for screens, 300 for print. Click to switch."));
|
||
// Each pill steps to the next and back round.
|
||
QTest::mouseClick(&background, Qt::LeftButton);
|
||
QCOMPARE(background.text(), QString("White canvas"));
|
||
fixture.create.click();
|
||
QTest::mouseClick(&background, Qt::LeftButton);
|
||
QCOMPARE(background.text(), QString("Black canvas"));
|
||
QTest::mouseClick(&resolution, Qt::LeftButton);
|
||
QCOMPARE(resolution.text(), QString("300 DPI"));
|
||
fixture.create.click();
|
||
QTest::mouseClick(&background, Qt::LeftButton);
|
||
QTest::mouseClick(&resolution, Qt::LeftButton);
|
||
QCOMPARE(background.text(), QString("Transparent canvas"));
|
||
QCOMPARE(resolution.text(), QString("72 DPI"));
|
||
fixture.create.click();
|
||
QCOMPARE(fixture.created, (QList<QSize>{QSize(1920, 1080), QSize(1920, 1080), QSize(1920, 1080)}));
|
||
QCOMPARE(fixture.resolutions, (QList<double>{72, 300, 72}));
|
||
QCOMPARE(fixture.backgrounds, (QList<std::optional<QColor>>{QColor(255, 255, 255), QColor(0, 0, 0), std::nullopt}));
|
||
// A pill is text alone; hovered, a capsule shows.
|
||
const QImage plain = background.grab().toImage();
|
||
QTest::mouseMove(&background);
|
||
QTRY_VERIFY(background.underMouse());
|
||
background.repaint();
|
||
QVERIFY(background.grab().toImage() != plain);
|
||
}
|
||
|
||
void NewCanvasSheetTests::printUnitsWriteTheSameCanvas()
|
||
{
|
||
Sheet fixture;
|
||
fixture.sheet.show();
|
||
QVERIFY(QTest::qWaitForWindowExposed(&fixture.sheet));
|
||
QAbstractButton &unit = *fixture.sheet.findChild<QAbstractButton *>("canvasUnit");
|
||
QAbstractButton &resolution = *fixture.sheet.findChild<QAbstractButton *>("canvasResolution");
|
||
QStringList labels;
|
||
for (const QLabel *label : fixture.sheet.findChildren<QLabel *>())
|
||
labels << label->text();
|
||
QCOMPARE(labels.count("px"), qsizetype(2));
|
||
unit.click();
|
||
QCOMPARE(unit.text(), QString("Inches"));
|
||
QCOMPARE(fixture.width.text(), QString("26.67"));
|
||
QCOMPARE(fixture.height.text(), QString("15"));
|
||
labels.clear();
|
||
for (const QLabel *label : fixture.sheet.findChildren<QLabel *>())
|
||
labels << label->text();
|
||
QCOMPARE(labels.count("in"), qsizetype(2));
|
||
QCOMPARE(fixture.checked(), QString("1080p"));
|
||
fixture.create.click();
|
||
// At 300 DPI the same inches make more pixels.
|
||
resolution.click();
|
||
QCOMPARE(resolution.toolTip(), QString("Resolution: 72 for screens, 300 for print. Click to switch. · 300 DPI: 8001 × 4500 pixels"));
|
||
QCOMPARE(fixture.checked(), QString("Custom"));
|
||
fixture.create.click();
|
||
QCOMPARE(fixture.created, (QList<QSize>{QSize(1920, 1080), QSize(8001, 4500)}));
|
||
// A preset is written in the unit in use.
|
||
fixture.entry("Instagram Square").trigger();
|
||
QCOMPARE(fixture.width.text(), QString("3.6"));
|
||
QCOMPARE(fixture.height.text(), QString("3.6"));
|
||
QCOMPARE(fixture.checked(), QString("Instagram Square"));
|
||
// With the height unreadable, a change of unit rewrites neither.
|
||
fixture.height.setText("tall");
|
||
unit.click();
|
||
QCOMPARE(fixture.width.text() + "x" + fixture.height.text(), QString("3.6xtall"));
|
||
unit.click();
|
||
unit.click();
|
||
unit.click();
|
||
QCOMPARE(unit.text(), QString("Inches"));
|
||
fixture.height.setText("3.6");
|
||
fixture.width.setText("200");
|
||
QVERIFY(!fixture.create.isEnabled() && !fixture.note.isHidden());
|
||
QCOMPARE(fixture.note.text(), QString("Enter a size up to 30,000 pixels at this DPI."));
|
||
// One side unreadable: a unit change rewrites neither.
|
||
unit.click();
|
||
QCOMPARE(unit.text(), QString("Centimeters"));
|
||
QCOMPARE(fixture.width.text(), QString("200"));
|
||
QCOMPARE(fixture.height.text(), QString("3.6"));
|
||
fixture.width.setText("30.48");
|
||
unit.click();
|
||
unit.click();
|
||
QCOMPARE(unit.text(), QString("Pixels"));
|
||
// The height's 3.6 was read in centimeters: 425 pixels.
|
||
QCOMPARE(fixture.width.text(), QString("3600"));
|
||
QCOMPARE(fixture.height.text(), QString("425"));
|
||
QCOMPARE(resolution.toolTip(), QString("Resolution: 72 for screens, 300 for print. Click to switch."));
|
||
QVERIFY(fixture.note.isHidden());
|
||
}
|
||
|
||
QTEST_MAIN(NewCanvasSheetTests)
|
||
#include "NewCanvasSheetTests.moc"
|