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