diff options
| author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2024-05-22 11:42:37 +0200 |
|---|---|---|
| committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2024-09-05 09:34:33 +0200 |
| commit | 9b0dc50ff1e8d5234eac94263659c68c2cb9524f (patch) | |
| tree | 1b3104b8edf43b7c58c8439a3ec559fe5363fb6e | |
| parent | 5aa3ac2fca9a144f177dec6b65f3e11dacd0300a (diff) | |
Add QDirListing
Task-number: PYSIDE-2620
Change-Id: I4e4826c5ab01a36022f43d2aa7d23558e6964a66
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io>
| -rw-r--r-- | sources/pyside6/PySide6/QtCore/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | sources/pyside6/PySide6/QtCore/glue/qtcorehelper.cpp | 66 | ||||
| -rw-r--r-- | sources/pyside6/PySide6/QtCore/typesystem_core_common.xml | 28 | ||||
| -rw-r--r-- | sources/pyside6/PySide6/glue/qtcore.cpp | 20 | ||||
| -rw-r--r-- | sources/pyside6/PySide6/qtcorehelper.h | 23 | ||||
| -rw-r--r-- | sources/pyside6/tests/QtCore/qdir_test.py | 11 |
6 files changed, 150 insertions, 1 deletions
diff --git a/sources/pyside6/PySide6/QtCore/CMakeLists.txt b/sources/pyside6/PySide6/QtCore/CMakeLists.txt index f3e4be0f9..369e81865 100644 --- a/sources/pyside6/PySide6/QtCore/CMakeLists.txt +++ b/sources/pyside6/PySide6/QtCore/CMakeLists.txt @@ -67,6 +67,8 @@ ${QtCore_GEN_DIR}/qdatetime_wrapper.cpp ${QtCore_GEN_DIR}/qdeadlinetimer_wrapper.cpp ${QtCore_GEN_DIR}/qdir_wrapper.cpp ${QtCore_GEN_DIR}/qdiriterator_wrapper.cpp +${QtCore_GEN_DIR}/qdirlisting_wrapper.cpp +${QtCore_GEN_DIR}/qdirlisting_direntry_wrapper.cpp ${QtCore_GEN_DIR}/qdynamicpropertychangeevent_wrapper.cpp ${QtCore_GEN_DIR}/qeasingcurve_wrapper.cpp ${QtCore_GEN_DIR}/qelapsedtimer_wrapper.cpp @@ -165,6 +167,7 @@ ${QtCore_GEN_DIR}/qstringlistmodel_wrapper.cpp ${QtCore_GEN_DIR}/qsysinfo_wrapper.cpp ${QtCore_GEN_DIR}/qsystemsemaphore_wrapper.cpp ${QtCore_GEN_DIR}/qt_wrapper.cpp +${QtCore_GEN_DIR}/qtcorehelper_qdirlistingiterator_wrapper.cpp ${QtCore_GEN_DIR}/qtcorehelper_qgenericargumentholder_wrapper.cpp ${QtCore_GEN_DIR}/qtcorehelper_qgenericreturnargumentholder_wrapper.cpp ${QtCore_GEN_DIR}/qtcorehelper_qiopipe_wrapper.cpp diff --git a/sources/pyside6/PySide6/QtCore/glue/qtcorehelper.cpp b/sources/pyside6/PySide6/QtCore/glue/qtcorehelper.cpp index 948c0ce5c..52e2f44c7 100644 --- a/sources/pyside6/PySide6/QtCore/glue/qtcorehelper.cpp +++ b/sources/pyside6/PySide6/QtCore/glue/qtcorehelper.cpp @@ -103,6 +103,72 @@ const void *QGenericReturnArgumentHolder::data() const return d->m_argument.data(); } +// QDirListing::const_iterator has no copy semantics (shared internal state, QTBUG-125512). +// The Python iterable semantics (calling __next__() first before retrieving the first value) +// can therefore not be implemented as "return iterator++;". Wrap a helper class +// around it that does a no-op in the first call to __next__(). +struct QDirListingIteratorPrivate +{ + enum State { First, Iterating, End }; + + explicit QDirListingIteratorPrivate(const QDirListing &dl) : + iterator(dl.cbegin()), state(First) {} + QDirListingIteratorPrivate() : state(End) {} + + bool next(); + + QDirListing::const_iterator iterator; + State state; +}; + +inline bool QDirListingIteratorPrivate::next() +{ + switch (state) { + case First: + state = iterator != QDirListing::const_iterator{} ? Iterating : End; + break; + case Iterating: + if (++iterator == QDirListing::const_iterator{}) + state = End; + break; + case End: + break; + } + return state != End; +} + +QDirListingIterator::QDirListingIterator(const QDirListing &dl) : + d(std::make_shared<QDirListingIteratorPrivate>(dl)) +{ +} + +QDirListingIterator::QDirListingIterator() : + d(std::make_shared<QDirListingIteratorPrivate>()) +{ +} + +QDirListingIterator::QDirListingIterator(const QDirListingIterator &) = default; +QDirListingIterator &QDirListingIterator::operator=(const QDirListingIterator &) = default; +QDirListingIterator::QDirListingIterator(QDirListingIterator &&) noexcept = default; +QDirListingIterator &QDirListingIterator::operator=(QDirListingIterator &&) noexcept = default; +QDirListingIterator::~QDirListingIterator() = default; + +bool QDirListingIterator::next() +{ + return d->next(); +} + +const QDirListing::DirEntry &QDirListingIterator::value() const +{ + Q_ASSERT(d->state == QDirListingIteratorPrivate::Iterating); + return *d->iterator; +} + +bool QDirListingIterator::atEnd() const +{ + return d->state == QDirListingIteratorPrivate::End; +} + } // namespace QtCoreHelper QT_END_NAMESPACE diff --git a/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml b/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml index 322be5fb1..accff6410 100644 --- a/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml +++ b/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml @@ -957,6 +957,23 @@ </add-function> </value-type> + <object-type name="QDirListing" since="6.8"> + <extra-includes> + <include file-name="qtcorehelper.h" location="local"/> + </extra-includes> + <enum-type name="IteratorFlag" flags="IteratorFlags"/> + <value-type name="DirEntry"> + <add-function signature="__repr__" return-type="PyObject*"> + <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" + snippet="qdirlisting-direntry-repr"/> + </add-function> + </value-type> + <add-function signature="__iter__()" return-type="PyObject*"> + <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" + snippet="qdirlisting-iter"/> + </add-function> + </object-type> + <value-type name="QPermission" since="6.5"> <configuration condition="QT_CONFIG(permissions)"/> </value-type> @@ -2482,6 +2499,17 @@ <object-type name="QIOPipe"/> <value-type name="QGenericArgumentHolder"/> <value-type name="QGenericReturnArgumentHolder"/> + <value-type name="QDirListingIterator"> + <add-function signature="__iter__()" return-type="PyObject*"> + <inject-code class="target" position="beginning"> + <insert-template name="__iter__"/> + </inject-code> + </add-function> + <add-function signature="__next__()" return-type="PyObject*"> + <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" + snippet="qdirlistingiterator-next"/> + </add-function> + </value-type> </namespace-type> <!-- Qt5 addition --> diff --git a/sources/pyside6/PySide6/glue/qtcore.cpp b/sources/pyside6/PySide6/glue/qtcore.cpp index 58fa5d4e5..4c138305a 100644 --- a/sources/pyside6/PySide6/glue/qtcore.cpp +++ b/sources/pyside6/PySide6/glue/qtcore.cpp @@ -2126,3 +2126,23 @@ PyRun_String(R"PY(if True: )PY", Py_file_input, _inputDict, _inputDict); // @snippet qt-modifier + +// @snippet qdirlisting-iter +auto result = QtCoreHelper::QDirListingIterator(*%CPPSELF); +%PYARG_0 = %CONVERTTOPYTHON[QtCoreHelper::QDirListingIterator](result); +// @snippet qdirlisting-iter + +// @snippet qdirlistingiterator-next +if (%CPPSELF.next()) { + Py_INCREF(%PYSELF); + %PYARG_0 = %PYSELF; +} +// @snippet qdirlistingiterator-next + +// @snippet qdirlisting-direntry-repr +QByteArray result = '<' + QByteArray(Py_TYPE(%PYSELF)->tp_name) + + " object at 0x" + + QByteArray::number(quintptr(%PYSELF), 16) + " (\"" + + %CPPSELF.absoluteFilePath().toUtf8() + "\")>"; +%PYARG_0 = Shiboken::String::fromCString(result.constData()); +// @snippet qdirlisting-direntry-repr diff --git a/sources/pyside6/PySide6/qtcorehelper.h b/sources/pyside6/PySide6/qtcorehelper.h index 589d0b295..6bce2f5f4 100644 --- a/sources/pyside6/PySide6/qtcorehelper.h +++ b/sources/pyside6/PySide6/qtcorehelper.h @@ -4,6 +4,7 @@ #ifndef QTCOREHELPER_H #define QTCOREHELPER_H +#include <QtCore/qdirlisting.h> #include <QtCore/qmutex.h> #include <QtCore/qobjectdefs.h> @@ -115,6 +116,28 @@ namespace QtCoreHelper { std::shared_ptr<QGenericReturnArgumentData> d; }; + struct QDirListingIteratorPrivate; + + class QDirListingIterator + { + public: + explicit QDirListingIterator(const QDirListing &dl); + QDirListingIterator(); + + QDirListingIterator(const QDirListingIterator &); + QDirListingIterator &operator=(const QDirListingIterator &); + QDirListingIterator(QDirListingIterator &&) noexcept; + QDirListingIterator &operator=(QDirListingIterator &&) noexcept; + ~QDirListingIterator(); + + bool next(); + const QDirListing::DirEntry &value() const; + bool atEnd() const; + + private: + std::shared_ptr<QDirListingIteratorPrivate> d; + }; + } // namespace QtCoreHelper QT_END_NAMESPACE diff --git a/sources/pyside6/tests/QtCore/qdir_test.py b/sources/pyside6/tests/QtCore/qdir_test.py index ba360629b..0cc1cfb56 100644 --- a/sources/pyside6/tests/QtCore/qdir_test.py +++ b/sources/pyside6/tests/QtCore/qdir_test.py @@ -11,7 +11,7 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) from init_paths import init_test_paths init_test_paths(False) -from PySide6.QtCore import QDir +from PySide6.QtCore import QDir, QDirListing class QDirTest(unittest.TestCase): @@ -36,5 +36,14 @@ class QDirTest(unittest.TestCase): self.assertEqual(b, c) +class QDirListingTest(unittest.TestCase): + '''Test case for QDirListing''' + + def test(self): + dir_listing = QDirListing(QDir.homePath()) + for entry in dir_listing: + pass + + if __name__ == '__main__': unittest.main() |
