File indexing completed on 2024-10-13 06:37:52
0001 /* 0002 This file is part of the KDE libraries 0003 SPDX-FileCopyrightText: 2018 Dominik Haumann <dhaumann@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "inlinenote_test.h" 0009 #include "moc_inlinenote_test.cpp" 0010 0011 #include <katedocument.h> 0012 #include <kateglobal.h> 0013 #include <kateview.h> 0014 #include <ktexteditor/inlinenote.h> 0015 #include <ktexteditor/inlinenoteprovider.h> 0016 0017 #include <QPainter> 0018 #include <QTemporaryFile> 0019 #include <QTest> 0020 #include <QTestMouseEvent> 0021 0022 using namespace KTextEditor; 0023 0024 QTEST_MAIN(InlineNoteTest) 0025 0026 namespace 0027 { 0028 QWidget *findViewInternal(KTextEditor::View *view) 0029 { 0030 for (QObject *child : view->children()) { 0031 if (child->metaObject()->className() == QByteArrayLiteral("KateViewInternal")) { 0032 return qobject_cast<QWidget *>(child); 0033 } 0034 } 0035 return nullptr; 0036 } 0037 0038 class NoteProvider : public InlineNoteProvider 0039 { 0040 public: 0041 QList<int> inlineNotes(int line) const override 0042 { 0043 if (line == 0) { 0044 return {5, 10}; 0045 } 0046 0047 return {}; 0048 } 0049 0050 QSize inlineNoteSize(const InlineNote ¬e) const override 0051 { 0052 if (note.position().column() == 5) { 0053 const auto xWidth = QFontMetrics(note.font()).boundingRect(QStringLiteral("x")).width(); 0054 return QSize(xWidth, note.lineHeight()); 0055 } else if (note.position().column() == 10) { 0056 return QSize(note.lineHeight(), note.lineHeight()); 0057 } 0058 0059 return QSize(); 0060 } 0061 0062 void paintInlineNote(const InlineNote ¬e, QPainter &painter, Qt::LayoutDirection) const override 0063 { 0064 if (note.position().column() == 5) { 0065 painter.setPen(Qt::darkGreen); 0066 painter.setBrush(Qt::green); 0067 painter.drawEllipse(1, 1, note.width() - 2, note.lineHeight() - 2); 0068 } else if (note.position().column() == 10) { 0069 painter.setPen(Qt::darkRed); 0070 if (note.underMouse()) { 0071 painter.setBrush(Qt::red); 0072 } else { 0073 painter.setBrush(Qt::yellow); 0074 } 0075 painter.drawRoundedRect(1, 1, note.width() - 2, note.lineHeight() - 2, 2, 2); 0076 } 0077 } 0078 0079 void inlineNoteActivated(const InlineNote ¬e, Qt::MouseButtons buttons, const QPoint &globalPos) override 0080 { 0081 Q_UNUSED(buttons) 0082 Q_UNUSED(globalPos) 0083 ++noteActivatedCount; 0084 lastUnderMouse = note.underMouse(); 0085 } 0086 0087 void inlineNoteFocusInEvent(const InlineNote ¬e, const QPoint &globalPos) override 0088 { 0089 Q_UNUSED(globalPos) 0090 ++focusInCount; 0091 lastUnderMouse = note.underMouse(); 0092 } 0093 0094 void inlineNoteFocusOutEvent(const InlineNote ¬e) override 0095 { 0096 ++focusOutCount; 0097 // Here it should not be under the mosu 0098 lastUnderMouse = note.underMouse(); 0099 } 0100 0101 void inlineNoteMouseMoveEvent(const InlineNote ¬e, const QPoint &globalPos) override 0102 { 0103 Q_UNUSED(globalPos) 0104 ++mouseMoveCount; 0105 lastUnderMouse = note.underMouse(); 0106 } 0107 0108 public: 0109 int noteActivatedCount = 0; 0110 int focusInCount = 0; 0111 int focusOutCount = 0; 0112 int mouseMoveCount = 0; 0113 bool lastUnderMouse = false; 0114 }; 0115 } 0116 0117 InlineNoteTest::InlineNoteTest() 0118 : QObject() 0119 { 0120 KTextEditor::EditorPrivate::enableUnitTestMode(); 0121 } 0122 0123 InlineNoteTest::~InlineNoteTest() 0124 { 0125 } 0126 0127 void InlineNoteTest::testInlineNote() 0128 { 0129 KTextEditor::DocumentPrivate doc; 0130 doc.setText(QStringLiteral("xxxxxxxxxx\nxxxxxxxxxx")); 0131 0132 KTextEditor::ViewPrivate view(&doc, nullptr); 0133 view.show(); 0134 view.resize(400, 300); 0135 0136 view.setCursorPosition({0, 5}); 0137 QCOMPARE(view.cursorPosition(), Cursor(0, 5)); 0138 0139 const auto coordCol04 = view.cursorToCoordinate({0, 4}); 0140 const auto coordCol05 = view.cursorToCoordinate({0, 5}); 0141 const auto coordCol10 = view.cursorToCoordinate({0, 10}); 0142 QVERIFY(coordCol05.x() > coordCol04.x()); 0143 QVERIFY(coordCol10.x() > coordCol05.x()); 0144 0145 const auto xWidth = coordCol05.x() - coordCol04.x(); 0146 0147 NoteProvider noteProvider; 0148 const QList<int> expectedColumns = {5, 10}; 0149 QCOMPARE(noteProvider.inlineNotes(0), expectedColumns); 0150 QCOMPARE(noteProvider.inlineNotes(1), QList<int>()); 0151 view.registerInlineNoteProvider(¬eProvider); 0152 0153 const auto newCoordCol04 = view.cursorToCoordinate({0, 4}); 0154 const auto newCoordCol05 = view.cursorToCoordinate({0, 5}); 0155 const auto newCoordCol10 = view.cursorToCoordinate({0, 10}); 0156 0157 QVERIFY(newCoordCol05.x() > newCoordCol04.x()); 0158 QVERIFY(newCoordCol10.x() > newCoordCol05.x()); 0159 0160 QCOMPARE(newCoordCol04, coordCol04); 0161 QVERIFY(newCoordCol05.x() > coordCol05.x()); 0162 QVERIFY(newCoordCol10.x() > coordCol10.x()); 0163 0164 // so far, we should not have any activation event 0165 QCOMPARE(noteProvider.noteActivatedCount, 0); 0166 QCOMPARE(noteProvider.focusInCount, 0); 0167 QCOMPARE(noteProvider.focusOutCount, 0); 0168 QCOMPARE(noteProvider.mouseMoveCount, 0); 0169 QVERIFY(noteProvider.lastUnderMouse == false); 0170 0171 // mouse move only on X11 0172 if (qApp->platformName() != QLatin1String("xcb")) { 0173 view.unregisterInlineNoteProvider(¬eProvider); 0174 QSKIP("mouse moving only on X11"); 0175 } 0176 0177 // move mouse onto first note 0178 auto internalView = findViewInternal(&view); 0179 QVERIFY(internalView); 0180 0181 // focus in 0182 QTest::mouseMove(&view, coordCol05 + QPoint(xWidth / 2, 1)); 0183 QTest::qWait(100); 0184 QCOMPARE(noteProvider.focusInCount, 1); 0185 QCOMPARE(noteProvider.focusOutCount, 0); 0186 QCOMPARE(noteProvider.mouseMoveCount, 0); 0187 QCOMPARE(noteProvider.noteActivatedCount, 0); 0188 QVERIFY(noteProvider.lastUnderMouse); 0189 0190 // move one pixel 0191 QTest::mouseMove(&view, coordCol05 + QPoint(xWidth / 2 + 1, 1)); 0192 QTest::qWait(100); 0193 QCOMPARE(noteProvider.focusInCount, 1); 0194 QCOMPARE(noteProvider.focusOutCount, 0); 0195 QCOMPARE(noteProvider.mouseMoveCount, 1); 0196 QCOMPARE(noteProvider.noteActivatedCount, 0); 0197 QVERIFY(noteProvider.lastUnderMouse); 0198 0199 // activate 0200 QTest::mousePress(internalView, Qt::LeftButton, Qt::NoModifier, internalView->mapFromGlobal(view.mapToGlobal(coordCol05 + QPoint(xWidth / 2 + 1, 1)))); 0201 QTest::mouseRelease(internalView, Qt::LeftButton, Qt::NoModifier, internalView->mapFromGlobal(view.mapToGlobal(coordCol05 + QPoint(xWidth / 2 + 1, 1)))); 0202 QTest::qWait(100); 0203 QCOMPARE(noteProvider.focusInCount, 1); 0204 QCOMPARE(noteProvider.focusOutCount, 0); 0205 QCOMPARE(noteProvider.mouseMoveCount, 1); 0206 QCOMPARE(noteProvider.noteActivatedCount, 1); 0207 QVERIFY(noteProvider.lastUnderMouse); 0208 0209 // focus out 0210 QTest::mouseMove(&view, coordCol04 + QPoint(0, 1)); 0211 QTest::mouseMove(&view, coordCol04 + QPoint(-1, 1)); 0212 QTest::qWait(200); 0213 QCOMPARE(noteProvider.focusInCount, 1); 0214 QCOMPARE(noteProvider.focusOutCount, 1); 0215 QCOMPARE(noteProvider.mouseMoveCount, 1); 0216 QCOMPARE(noteProvider.noteActivatedCount, 1); 0217 QVERIFY(noteProvider.lastUnderMouse == false); 0218 0219 view.unregisterInlineNoteProvider(¬eProvider); 0220 } 0221 0222 // kate: indent-mode cstyle; indent-width 4; replace-tabs on;