File indexing completed on 2024-04-28 15:31:54
0001 /* 0002 SPDX-FileCopyrightText: 2017 Elvis Angelaccio <elvis.angelaccio@kde.org> 0003 SPDX-FileCopyrightText: 2018 Michael Heidelbach <ottwolt@gmail.com> 0004 0005 SPDX-License-Identifier: LGPL-2.1-or-later 0006 */ 0007 0008 #include "ktooltipwidgettest.h" 0009 0010 #include <KToolTipWidget> 0011 0012 #include <QLabel> 0013 #include <QLayout> 0014 #include <QLineEdit> 0015 #include <QScreen> 0016 #include <QSignalSpy> 0017 #include <QStyle> 0018 #include <QTest> 0019 0020 void KToolTipWidgetTest::initTestCase() 0021 { 0022 m_screenGeometry = QGuiApplication::primaryScreen()->geometry(); 0023 } 0024 0025 void KToolTipWidgetTest::showTooltipShouldShowContent() 0026 { 0027 KToolTipWidget tooltip; 0028 QLabel label; 0029 0030 tooltip.showAt(QPoint(10, 10), &label, nullptr); 0031 QVERIFY(tooltip.isVisible()); 0032 QVERIFY(label.isVisible()); 0033 } 0034 0035 void KToolTipWidgetTest::hideLaterShouldHideAfterDelay() 0036 { 0037 KToolTipWidget tooltip; 0038 QLabel label; 0039 0040 tooltip.showAt(QPoint(10, 10), &label, nullptr); 0041 QVERIFY(tooltip.isVisible()); 0042 QVERIFY(label.isVisible()); 0043 0044 tooltip.hideLater(); 0045 QVERIFY(tooltip.isVisible()); 0046 QVERIFY(label.isVisible()); 0047 0048 QSignalSpy spy(&tooltip, &KToolTipWidget::hidden); 0049 connect(&tooltip, &KToolTipWidget::hidden, this, [&]() { 0050 QVERIFY(tooltip.isHidden()); 0051 QVERIFY(!label.isVisible()); 0052 }); 0053 0054 QEventLoop eventLoop; 0055 connect(&tooltip, &KToolTipWidget::hidden, &eventLoop, &QEventLoop::quit); 0056 QCOMPARE(eventLoop.exec(), 0); 0057 QCOMPARE(spy.count(), 1); 0058 } 0059 0060 void KToolTipWidgetTest::setZeroDelayShouldHideImmediately() 0061 { 0062 KToolTipWidget tooltip; 0063 QLabel label; 0064 0065 tooltip.setHideDelay(0); 0066 tooltip.showAt(QPoint(10, 10), &label, nullptr); 0067 QVERIFY(tooltip.isVisible()); 0068 QVERIFY(label.isVisible()); 0069 0070 tooltip.hideLater(); 0071 QVERIFY(tooltip.isHidden()); 0072 QVERIFY(!label.isVisible()); 0073 } 0074 0075 void KToolTipWidgetTest::shouldHideImmediatelyIfContentDestroyed() 0076 { 0077 KToolTipWidget tooltip; 0078 auto lineEdit = new QLineEdit(); 0079 0080 tooltip.showAt(QPoint(10, 10), lineEdit, nullptr); 0081 QVERIFY(tooltip.isVisible()); 0082 0083 delete lineEdit; 0084 QVERIFY(tooltip.isHidden()); 0085 } 0086 0087 void KToolTipWidgetTest::shouldNotTakeOwnershipOfContent() 0088 { 0089 auto parent = new QWidget(); 0090 auto label = new QLabel(parent); 0091 auto tooltip = new KToolTipWidget(); 0092 0093 tooltip->showAt(QPoint(10, 10), label, nullptr); 0094 QCOMPARE(label->parent(), tooltip); 0095 QVERIFY(label->isVisible()); 0096 0097 QSignalSpy spy(label, &QWidget::destroyed); 0098 delete tooltip; 0099 QVERIFY(!label->isVisible()); 0100 QCOMPARE(label->parent(), parent); 0101 QCOMPARE(spy.count(), 0); 0102 0103 delete parent; 0104 QCOMPARE(spy.count(), 1); 0105 } 0106 0107 void KToolTipWidgetTest::shouldNotObscureTarget_data() 0108 { 0109 qDebug() << "Style used" << QApplication::style()->objectName(); 0110 0111 QTest::addColumn<QPoint>("position"); 0112 QTest::addColumn<QString>("content"); 0113 0114 const QMap<QString, QPoint> positions{{QStringLiteral("topleft"), QPoint(m_offset, m_offset)}, 0115 {QStringLiteral("topright"), QPoint(-m_offset, m_offset)}, 0116 {QStringLiteral("bottomright"), QPoint(-m_offset, -m_offset)}, 0117 {QStringLiteral("bottomleft"), QPoint(m_offset, -m_offset)}, 0118 {QStringLiteral("centered"), QPoint(m_screenGeometry.width() / 2, m_screenGeometry.height() / 2)}}; 0119 0120 QMapIterator<QString, QPoint> i(positions); 0121 while (i.hasNext()) { 0122 i.next(); 0123 QTest::newRow(qPrintable(QStringLiteral("small/%1").arg(i.key()))) << i.value() << QStringLiteral("dummy text"); 0124 0125 QTest::newRow(qPrintable(QStringLiteral("multiline/%1").arg(i.key()))) << i.value() << QStringLiteral("dummy text\nLine 1\nLine 2\nLine 3"); 0126 0127 QTest::newRow(qPrintable(QStringLiteral("one long line/%1").arg(i.key()))) 0128 << i.value() 0129 << QStringLiteral( 0130 "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam nec felis sed elit auctor lobortis non a urna. Quisque non posuere mauris. " 0131 "Suspendisse potenti. In diam leo, lobortis at placerat nec, sagittis at tortor. Pellentesque scelerisque enim vel elementum scelerisque. " 0132 "Integer eget lectus vitae lorem pulvinar hendrerit. Suspendisse auctor sapien vel semper porta. Vestibulum fringilla aliquet tincidunt. " 0133 "Maecenas mollis mauris et erat viverra mollis. Proin suscipit felis nisi, a dapibus est hendrerit euismod. Suspendisse quis faucibus quam. " 0134 "Fusce eu cursus magna, et egestas purus. Duis enim sapien, feugiat id facilisis non, rhoncus ut lectus. Aliquam at nisi vel ligula " 0135 "interdum ultricies. Donec condimentum ante quam, eu congue lectus pulvinar in. Cras interdum, neque quis fermentum consequat, lectus " 0136 "tellus eleifend turpis."); 0137 0138 if (m_screenGeometry.width() >= 1600 && m_screenGeometry.height() >= 900) { 0139 QTest::newRow(qPrintable(QStringLiteral("super large/%1").arg(i.key()))) 0140 << i.value() 0141 << QStringLiteral( 0142 "dummy 0 text\nLine 1\nLine 2\nLine 3" 0143 "dummy 1 text\nLine 1\nLine 2\nLine 3" 0144 "dummy 2 text\nLine 1\nLine 2\nLine 3" 0145 "dummy 3 text\nLine 1\nLine 2\nLine 3" 0146 "dummy 4 text\nLine 1\nLine 2\nLine 3" 0147 0148 "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam nec felis sed elit auctor lobortis non a urna. Quisque non posuere " 0149 "mauris. Suspendisse potenti. In diam leo, lobortis at placerat nec, sagittis at tortor. Pellentesque scelerisque enim vel elementum " 0150 "scelerisque. Integer eget lectus vitae lorem pulvinar hendrerit. Suspendisse auctor sapien vel semper porta. Vestibulum fringilla " 0151 "aliquet tincidunt. Maecenas mollis mauris et erat viverra mollis. Proin suscipit felis nisi, a dapibus est hendrerit euismod. " 0152 "Suspendisse quis faucibus quam. Fusce eu cursus magna, et egestas purus. Duis enim sapien, feugiat id facilisis non, rhoncus ut " 0153 "lectus. Aliquam at nisi vel ligula interdum ultricies. Donec condimentum ante quam, eu congue lectus pulvinar in. Cras interdum, neque " 0154 "quis fermentum consequat, lectus tellus eleifend turpis."); 0155 } 0156 } 0157 } 0158 0159 void KToolTipWidgetTest::shouldNotObscureTarget() 0160 { 0161 QFETCH(QPoint, position); 0162 QFETCH(QString, content); 0163 0164 QWidget *containerWidget = new QWidget(); 0165 const int margin = containerWidget->style()->pixelMetric(QStyle::PM_ToolTipLabelFrameWidth); 0166 QLabel *targetWidget = new QLabel(QStringLiteral("dummy file")); 0167 QLayout *layout = new QHBoxLayout(containerWidget); 0168 layout->addWidget(targetWidget); 0169 0170 containerWidget->adjustSize(); 0171 containerWidget->move(position.x() >= 0 ? position.x() : m_screenGeometry.right() + position.x() - containerWidget->width(), 0172 position.y() >= 0 ? position.y() : m_screenGeometry.bottom() + position.y() - containerWidget->height()); 0173 containerWidget->show(); 0174 QVERIFY(QTest::qWaitForWindowExposed(containerWidget)); 0175 QVERIFY(targetWidget->isVisible()); 0176 0177 QRect targetRect = QRect(targetWidget->frameGeometry()); 0178 targetRect.moveTo(targetWidget->mapToGlobal(QPoint(0, 0))); 0179 0180 QLabel *contentWidget = new QLabel(content); 0181 0182 QVERIFY2(containerWidget->windowHandle(), "Container's window handle is invalid"); 0183 KToolTipWidget tooltipWidget; 0184 tooltipWidget.showBelow(targetRect, contentWidget, containerWidget->windowHandle()); 0185 QVERIFY(QTest::qWaitForWindowExposed(&tooltipWidget)); 0186 const QRect tooltipRect = tooltipWidget.frameGeometry(); 0187 0188 qDebug() << QStringLiteral("tooltip: %1x%2 x=%3, y=%4").arg(tooltipRect.width()).arg(tooltipRect.height()).arg(tooltipRect.left()).arg(tooltipRect.top()); 0189 qDebug() << QStringLiteral("target: %1x%2 x=%3, y=%4").arg(targetRect.width()).arg(targetRect.height()).arg(targetRect.left()).arg(targetRect.top()); 0190 0191 QVERIFY2(!tooltipRect.intersects(targetRect), "Target obscured"); 0192 QCOMPARE(tooltipRect.intersected(m_screenGeometry), tooltipRect); 0193 0194 // Check margins 0195 if (tooltipRect.bottom() < targetRect.top()) { 0196 QCOMPARE(margin, targetRect.top() - tooltipRect.bottom()); 0197 } else if (tooltipRect.top() > targetRect.bottom()) { 0198 QCOMPARE(margin, tooltipRect.top() - targetRect.bottom()); 0199 } else if (tooltipRect.right() < targetRect.left()) { 0200 QCOMPARE(margin, targetRect.left() - tooltipRect.right()); 0201 } else if (tooltipRect.left() > targetRect.right()) { 0202 QCOMPARE(margin, tooltipRect.left() - targetRect.right()); 0203 } 0204 0205 tooltipWidget.hide(); 0206 QVERIFY(tooltipWidget.isHidden()); 0207 0208 delete contentWidget; 0209 delete containerWidget; 0210 } 0211 0212 QTEST_MAIN(KToolTipWidgetTest) 0213 0214 #include "moc_ktooltipwidgettest.cpp"