aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2024-05-22 11:42:37 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2024-09-05 09:34:33 +0200
commit9b0dc50ff1e8d5234eac94263659c68c2cb9524f (patch)
tree1b3104b8edf43b7c58c8439a3ec559fe5363fb6e
parent5aa3ac2fca9a144f177dec6b65f3e11dacd0300a (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.txt3
-rw-r--r--sources/pyside6/PySide6/QtCore/glue/qtcorehelper.cpp66
-rw-r--r--sources/pyside6/PySide6/QtCore/typesystem_core_common.xml28
-rw-r--r--sources/pyside6/PySide6/glue/qtcore.cpp20
-rw-r--r--sources/pyside6/PySide6/qtcorehelper.h23
-rw-r--r--sources/pyside6/tests/QtCore/qdir_test.py11
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()