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();
53 if (directory.startsWith(
"assets-library:"_L1) || scheme ==
"assets-library"_L1)
54 return showImagePickerDialog(parent);
56 return showNativeDocumentPickerDialog(parent);
62void QIOSFileDialog::showImagePickerDialog_helper(QWindow *parent)
64 UIWindow *window = presentationWindow(parent);
65 [window.rootViewController presentViewController:m_viewController animated:YES completion:nil];
68bool QIOSFileDialog::showImagePickerDialog(QWindow *parent)
70 if (!m_viewController) {
72 qsizetype size = QList<QPluginParsedMetaData>(plugins->metaData()).size();
73 for (qsizetype i = 0; i < size; ++i) {
74 QIosOptionalPluginInterface *plugin = qobject_cast<QIosOptionalPluginInterface *>(plugins->instance(i));
75 m_viewController = [plugin->createImagePickerController(
this) retain];
81 if (!m_viewController) {
82 qWarning() <<
"QIOSFileDialog: Could not resolve Qt plugin that gives access to photos on iOS";
95 const auto authStatus = [PHPhotoLibrary authorizationStatus];
96 if (authStatus == PHAuthorizationStatusAuthorized) {
97 showImagePickerDialog_helper(parent);
98 }
else if (authStatus == PHAuthorizationStatusNotDetermined) {
99 QPointer<QWindow> winGuard(parent);
100 QPointer<QIOSFileDialog> thisGuard(
this);
101 [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
102 dispatch_async(dispatch_get_main_queue(), ^{
103 if (status == PHAuthorizationStatusAuthorized) {
104 if (thisGuard && (winGuard || !parent))
105 thisGuard->showImagePickerDialog_helper(winGuard);
107 }
else if (thisGuard) {
108 emit thisGuard->reject();
115 qWarning() <<
"QIOSFileDialog: insufficient permission, cannot pick images";
122bool QIOSFileDialog::showNativeDocumentPickerDialog(QWindow *parent)
125 m_viewController = [[QIOSDocumentPickerController alloc] initWithQIOSFileDialog:
this];
127 UIWindow *window = presentationWindow(parent);
128 [window.rootViewController presentViewController:m_viewController animated:YES completion:nil];
136void QIOSFileDialog::hide()
144 emit directoryEntered(QUrl::fromLocalFile(QDir::currentPath()));
146 [m_viewController dismissViewControllerAnimated:YES completion:nil];
147 [m_viewController release];
148 m_viewController =
nullptr;
152QList<QUrl> QIOSFileDialog::selectedFiles()
const
157void QIOSFileDialog::selectedFilesChanged(
const QList<QUrl> &selection)
159 m_selection = selection;
160 emit filesSelected(m_selection);
161 if (m_selection.count() == 1)
162 emit fileSelected(m_selection[0]);
static QIOSIntegration * instance()