7#import <AssetsLibrary/AssetsLibrary.h>
9#include <QtCore/QTimer>
10#include <QtCore/private/qcoreapplication_p.h>
11#include <QtCore/qurl.h>
12#include <QtCore/qset.h>
13#include <QtCore/qthreadstorage.h>
14#include <QtCore/qfileselector.h>
15#include <QtCore/qpointer.h>
29 if ([ALAssetsLibrary authorizationStatus] != ALAuthorizationStatusNotDetermined)
35 if ([NSThread isMainThread]) {
45 NSLog(
@"QIOSFileEngine: unable to show assets authorization dialog from non-gui thread before QApplication is executing.");
58 : m_semWriteAsset(dispatch_semaphore_create(
kBufferSize))
59 , m_semReadAsset(dispatch_semaphore_create(0))
61 , m_assetsLibrary([assetsLibrary retain])
66 , m_nextAssetReady(
false)
85 dispatch_semaphore_signal(m_semWriteAsset);
86 dispatch_release(m_semReadAsset);
87 dispatch_release(m_semWriteAsset);
89 [m_assetsLibrary autorelease];
94 if (!m_nextAssetReady) {
95 dispatch_semaphore_wait(m_semReadAsset, DISPATCH_TIME_FOREVER);
96 m_nextAssetReady =
true;
98 return m_buffer[m_readIndex] !=
kNoAsset;
106 ALAsset *asset = [m_buffer[m_readIndex] autorelease];
107 dispatch_semaphore_signal(m_semWriteAsset);
110 m_nextAssetReady =
false;
115 dispatch_semaphore_t m_semWriteAsset;
116 dispatch_semaphore_t m_semReadAsset;
117 std::atomic_bool m_stop;
119 ALAssetsLibrary *m_assetsLibrary;
120 ALAssetsGroupType m_type;
121 QVector<ALAsset *> m_buffer;
124 bool m_nextAssetReady;
126 void writeAsset(ALAsset *asset)
128 dispatch_semaphore_wait(m_semWriteAsset, DISPATCH_TIME_FOREVER);
129 m_buffer[m_writeIndex] = [asset retain];
130 dispatch_semaphore_signal(m_semReadAsset);
134 void startEnumerate()
136 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
137 [m_assetsLibrary enumerateGroupsWithTypes:m_type usingBlock:^(ALAssetsGroup *
group, BOOL *stopEnumerate) {
145 *stopEnumerate =
true;
151 if (!asset || ![[asset valueForProperty:ALAssetPropertyType]
isEqual:ALAssetTypePhoto])
155 *stopEnumerate = m_stop;
157 } failureBlock:^(NSError *
error) {
158 NSLog(
@"QIOSFileEngine: %@",
error);
173 , m_assetUrl(assetUrl)
184 if (assetData->m_assetUrl == assetUrl) {
185 m_assetLibrary = [assetData->m_assetLibrary retain];
186 m_asset = [assetData->m_asset retain];
196 dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
198 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
199 NSURL *
url = [NSURL URLWithString:assetUrl.toNSString()];
200 m_assetLibrary = [[ALAssetsLibrary alloc]
init];
201 [m_assetLibrary assetForURL:
url resultBlock:^(ALAsset *asset) {
210 ALAsset *
a = e.
next();
212 if (
url == assetUrl) {
223 dispatch_semaphore_signal(semaphore);
224 } failureBlock:^(NSError *
error) {
226 dispatch_semaphore_signal(semaphore);
230 dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
231 dispatch_release(semaphore);
248 ALAssetsLibrary *m_assetLibrary;
253#ifndef QT_NO_FILESYSTEMITERATOR
283 QString url = QUrl::fromNSURL([asset valueForProperty:ALAssetPropertyAssetURL]).
toString();
315ALAsset *QIOSFileEngineAssetsLibrary::loadAsset()
const
323 std::optional<QFile::Permissions> permissions)
345 QAbstractFileEngine::FileFlags
flags;
346 const bool isDir = (m_assetUrl ==
"assets-library://"_L1);
349 static const auto selectors = fileSelector.
allSelectors();
350 if (m_assetUrl.
startsWith(
"assets-library://"_L1)) {
351 for (
const auto &
selector : selectors) {
366 ALAuthorizationStatus status = [ALAssetsLibrary authorizationStatus];
367 if (status != ALAuthorizationStatusRestricted && status != ALAuthorizationStatusDenied)
378 if (ALAsset *asset = loadAsset())
379 return [[asset defaultRepresentation]
size];
385 ALAsset *asset = loadAsset();
393 NSError *
error =
nullptr;
394 [[asset defaultRepresentation] getBytes:(uint8_t *)
data fromOffset:m_offset
length:bytesRead
error:&
error];
401 m_offset += bytesRead;
434 m_assetUrl =
"assets-library://"_L1;
436 m_assetUrl =
"assets-library:/"_L1 +
file.mid(
index);
439#ifndef QT_NO_FILESYSTEMITERATOR
445 return std::make_unique<QIOSFileEngineIteratorAssetsLibrary>(
path,
filters, filterNames);
static bool isEqual(const aiUVTransform &a, const aiUVTransform &b)
The QAbstractFileEngineIterator class provides an iterator interface for custom file engines.
QDir::Filters filters() const
Returns the entry filters for this iterator.
virtual QString currentFileName() const =0
This pure virtual function returns the name of the current directory entry, excluding the path.
QStringList nameFilters() const
Returns the name filters for this iterator.
virtual QFileInfo currentFileInfo() const
The virtual function returns a QFileInfo for the current directory entry.
virtual bool advance()=0
This pure virtual function advances the iterator to the next directory entry; if the operation was su...
std::unique_ptr< Iterator > IteratorUniquePtr
FileName
These values are used to request a file name in a particular format.
QFile::FileError error() const
Returns the QFile::FileError that resulted from the last failed operation.
int exec(ProcessEventsFlags flags=AllEvents)
Enters the main event loop and waits until exit() is called.
void quit()
Tells the event loop to exit normally.
QStringList allSelectors() const
Returns the complete, ordered list of selectors used by this instance.
QIOSAssetData(const QString &assetUrl, QIOSFileEngineAssetsLibrary *engine)
QIOSAssetEnumerator(ALAssetsLibrary *assetsLibrary, ALAssetsGroupType type)
~QIOSFileEngineAssetsLibrary()
QString fileName(FileName file) const override
Return the file engine's current file name in the format specified by file.
void setError(QFile::FileError error, const QString &str)
bool open(QIODevice::OpenMode openMode, std::optional< QFile::Permissions > permissions) override
Opens the file in the specified mode.
qint64 pos() const override
Returns the current file position.
void setFileName(const QString &file) override
Sets the file engine's file name to file.
IteratorUniquePtr beginEntryList(const QString &path, QDir::Filters filters, const QStringList &filterNames) override
Returns a QAbstractFileEngine::IteratorUniquePtr, that can be used to iterate over the entries in pat...
bool seek(qint64 pos) override
Sets the file position to the given offset.
FileFlags fileFlags(FileFlags type) const override
This function should return the set of OR'd flags that are true for the file engine's file,...
qint64 read(char *data, qint64 maxlen) override
Reads a number of characters from the file into data.
qint64 size() const override
Returns the size of the file.
QIOSFileEngineAssetsLibrary(const QString &fileName)
bool close() override
Closes the file, returning true if successful; otherwise returns false.
QIOSAssetEnumerator * m_enumerator
static QObjectPrivate * get(QObject *o)
void deleteLater()
\threadsafe
\macro QT_RESTRICTED_CAST_FROM_ASCII
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
bool singleShot
whether the timer is a single-shot timer
Combined button and popup list for selecting options.
DBusConnection const char DBusError * error
static bool ensureAuthorizationDialogNotBlocked()
static const int kBufferSize
static QThreadStorage< QString > g_iteratorCurrentUrl
static QThreadStorage< QPointer< QIOSAssetData > > g_assetDataCache
static ALAsset * kNoAsset
constexpr const T & qMin(const T &a, const T &b)
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLenum GLsizei length
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLsizei const GLchar *const * path
static QT_BEGIN_NAMESPACE void init(QTextBoundaryFinder::BoundaryType type, QStringView str, QCharAttributes *attributes)
QFileSelector selector
[1]
QUrl url("example.com")
[constructor-url-reference]
const QStringList filters({"Image files (*.png *.xpm *.jpg)", "Text files (*.txt)", "Any files (*)" })
[6]
char * toString(const MyType &t)
[31]