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)
31 connect(
this, &QPlatformFileDialogHelper::filesSelected,
32 this, &QIOSFileDialog::selectedFilesChanged);
35QIOSFileDialog::~QIOSFileDialog()
37 [m_viewController release];
40void QIOSFileDialog::exec()
42 m_eventLoop.exec(QEventLoop::DialogExec);
45bool QIOSFileDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
47 Q_UNUSED(windowFlags);
48 Q_UNUSED(windowModality);
50 const bool acceptOpen = options()->acceptMode() == QFileDialogOptions::AcceptOpen;
51 const auto initialDir = options()->initialDirectory();
52 const QString directory = initialDir.toLocalFile();
55 const QString scheme = initialDir.scheme();
57 if (acceptOpen && (directory.startsWith(
"assets-library:"_L1) || scheme ==
"assets-library"_L1))
58 return showImagePickerDialog(parent);
60 return showNativeDocumentPickerDialog(parent);
63void QIOSFileDialog::showImagePickerDialog_helper(QWindow *parent)
65 UIWindow *window = presentationWindow(parent);
66 [window.rootViewController presentViewController:m_viewController animated:YES completion:nil];
69bool QIOSFileDialog::showImagePickerDialog(QWindow *parent)
71 if (!m_viewController) {
73 qsizetype size = QList<QPluginParsedMetaData>(plugins->metaData()).size();
74 for (qsizetype i = 0; i < size; ++i) {
75 QIosOptionalPluginInterface *plugin = qobject_cast<QIosOptionalPluginInterface *>(plugins->instance(i));
76 m_viewController = [plugin->createImagePickerController(
this) retain];
82 if (!m_viewController) {
83 qWarning() <<
"QIOSFileDialog: Could not resolve Qt plugin that gives access to photos on iOS";
96 const auto authStatus = [PHPhotoLibrary authorizationStatus];
97 if (authStatus == PHAuthorizationStatusAuthorized) {
98 showImagePickerDialog_helper(parent);
99 }
else if (authStatus == PHAuthorizationStatusNotDetermined) {
100 QPointer<QWindow> winGuard(parent);
101 QPointer<QIOSFileDialog> thisGuard(
this);
102 [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
103 dispatch_async(dispatch_get_main_queue(), ^{
104 if (status == PHAuthorizationStatusAuthorized) {
105 if (thisGuard && (winGuard || !parent))
106 thisGuard->showImagePickerDialog_helper(winGuard);
108 }
else if (thisGuard) {
109 emit thisGuard->reject();
116 qWarning() <<
"QIOSFileDialog: insufficient permission, cannot pick images";
123bool QIOSFileDialog::showNativeDocumentPickerDialog(QWindow *parent)
126 m_viewController = [[QIOSDocumentPickerController alloc] initWithQIOSFileDialog:
this];
128 UIWindow *window = presentationWindow(parent);
129 [window.rootViewController presentViewController:m_viewController animated:YES completion:nil];
137void QIOSFileDialog::hide()
145 emit directoryEntered(QUrl::fromLocalFile(QDir::currentPath()));
147 [m_viewController dismissViewControllerAnimated:YES completion:nil];
148 [m_viewController release];
149 m_viewController =
nullptr;
153QList<QUrl> QIOSFileDialog::selectedFiles()
const
158void QIOSFileDialog::selectedFilesChanged(
const QList<QUrl> &selection)
160 m_selection = selection;
161 if (m_selection.count() == 1)
162 emit fileSelected(m_selection[0]);
static QIOSIntegration * instance()