7#import <Photos/Photos.h>
9#include <QtCore/qstandardpaths.h>
10#include <QtGui/qwindow.h>
13#include <QtCore/private/qcore_mac_p.h>
21#include <QtCore/qpointer.h>
23using namespace Qt::StringLiterals;
25QIOSFileDialog::QIOSFileDialog()
26 : m_viewController(
nullptr)
30QIOSFileDialog::~QIOSFileDialog()
32 [m_viewController release];
35void QIOSFileDialog::exec()
37 m_eventLoop.exec(QEventLoop::DialogExec);
40bool QIOSFileDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
42 Q_UNUSED(windowFlags);
43 Q_UNUSED(windowModality);
45 const bool acceptOpen = options()->acceptMode() == QFileDialogOptions::AcceptOpen;
46 const auto initialDir = options()->initialDirectory();
47 const QString directory = initialDir.toLocalFile();
50 const QString scheme = initialDir.scheme();
52 if (acceptOpen && (directory.startsWith(
"assets-library:"_L1) || scheme ==
"assets-library"_L1))
53 return showImagePickerDialog(parent);
55 return showNativeDocumentPickerDialog(parent);
58void QIOSFileDialog::showImagePickerDialog_helper(QWindow *parent)
60 UIWindow *window = presentationWindow(parent);
61 [window.rootViewController presentViewController:m_viewController animated:YES completion:nil];
64bool QIOSFileDialog::showImagePickerDialog(QWindow *parent)
66 if (!m_viewController) {
68 qsizetype size = QList<QPluginParsedMetaData>(plugins->metaData()).size();
69 for (qsizetype i = 0; i < size; ++i) {
70 QIosOptionalPluginInterface *plugin = qobject_cast<QIosOptionalPluginInterface *>(plugins->instance(i));
71 m_viewController = [plugin->createImagePickerController(
this) retain];
77 if (!m_viewController) {
78 qWarning() <<
"QIOSFileDialog: Could not resolve Qt plugin that gives access to photos on iOS";
91 const auto authStatus = [PHPhotoLibrary authorizationStatus];
92 if (authStatus == PHAuthorizationStatusAuthorized) {
93 showImagePickerDialog_helper(parent);
94 }
else if (authStatus == PHAuthorizationStatusNotDetermined) {
95 QPointer<QWindow> winGuard(parent);
96 QPointer<QIOSFileDialog> thisGuard(
this);
97 [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
98 dispatch_async(dispatch_get_main_queue(), ^{
99 if (status == PHAuthorizationStatusAuthorized) {
100 if (thisGuard && (winGuard || !parent))
101 thisGuard->showImagePickerDialog_helper(winGuard);
103 }
else if (thisGuard) {
104 emit thisGuard->reject();
111 qWarning() <<
"QIOSFileDialog: insufficient permission, cannot pick images";
118bool QIOSFileDialog::showNativeDocumentPickerDialog(QWindow *parent)
121 m_viewController = [[QIOSDocumentPickerController alloc] initWithQIOSFileDialog:
this];
123 UIWindow *window = presentationWindow(parent);
124 [window.rootViewController presentViewController:m_viewController animated:YES completion:nil];
132void QIOSFileDialog::hide()
140 emit directoryEntered(QUrl::fromLocalFile(QDir::currentPath()));
142 [m_viewController dismissViewControllerAnimated:YES completion:nil];
143 [m_viewController release];
144 m_viewController =
nullptr;
148QList<QUrl> QIOSFileDialog::selectedFiles()
const
153void QIOSFileDialog::selectedFilesChanged(
const QList<QUrl> &selection)
155 m_selection = selection;
156 emit filesSelected(m_selection);
157 if (m_selection.count() == 1)
158 emit fileSelected(m_selection[0]);
static QIOSIntegration * instance()