diff options
Diffstat (limited to 'src/plugins/platforms/ios/qiosfiledialog.mm')
-rw-r--r-- | src/plugins/platforms/ios/qiosfiledialog.mm | 59 |
1 files changed, 51 insertions, 8 deletions
diff --git a/src/plugins/platforms/ios/qiosfiledialog.mm b/src/plugins/platforms/ios/qiosfiledialog.mm index 3568a9e908..cf9580c17e 100644 --- a/src/plugins/platforms/ios/qiosfiledialog.mm +++ b/src/plugins/platforms/ios/qiosfiledialog.mm @@ -3,17 +3,22 @@ #import <UIKit/UIKit.h> +#import <Photos/Photos.h> + #include <QtCore/qstandardpaths.h> #include <QtGui/qwindow.h> #include <QDebug> #include <QtCore/private/qcore_mac_p.h> +#include "qiosglobal.h" #include "qiosfiledialog.h" #include "qiosintegration.h" #include "qiosoptionalplugininterface.h" #include "qiosdocumentpickercontroller.h" +#include <QtCore/qpointer.h> + using namespace Qt::StringLiterals; QIOSFileDialog::QIOSFileDialog() @@ -36,11 +41,15 @@ bool QIOSFileDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality window Q_UNUSED(windowFlags); Q_UNUSED(windowModality); - bool acceptOpen = options()->acceptMode() == QFileDialogOptions::AcceptOpen; - QString directory = options()->initialDirectory().toLocalFile(); + const bool acceptOpen = options()->acceptMode() == QFileDialogOptions::AcceptOpen; + const auto initialDir = options()->initialDirectory(); + const QString directory = initialDir.toLocalFile(); + // We manually add assets-library:// to the list of paths, + // when converted to QUrl, it becames a scheme. + const QString scheme = initialDir.scheme(); if (acceptOpen) { - if (directory.startsWith("assets-library:"_L1)) + if (directory.startsWith("assets-library:"_L1) || scheme == "assets-library"_L1) return showImagePickerDialog(parent); else return showNativeDocumentPickerDialog(parent); @@ -49,6 +58,12 @@ bool QIOSFileDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality window return false; } +void QIOSFileDialog::showImagePickerDialog_helper(QWindow *parent) +{ + UIWindow *window = presentationWindow(parent); + [window.rootViewController presentViewController:m_viewController animated:YES completion:nil]; +} + bool QIOSFileDialog::showImagePickerDialog(QWindow *parent) { if (!m_viewController) { @@ -67,9 +82,38 @@ bool QIOSFileDialog::showImagePickerDialog(QWindow *parent) return false; } - UIWindow *window = parent ? reinterpret_cast<UIView *>(parent->winId()).window - : qt_apple_sharedApplication().keyWindow; - [window.rootViewController presentViewController:m_viewController animated:YES completion:nil]; + // "Old style" authorization (deprecated, but we have to work with AssetsLibrary anyway). + // + // From the documentation: + // "The authorizationStatus and requestAuthorization: methods aren’t compatible with the + // limited library and return PHAuthorizationStatusAuthorized when the user authorizes your + // app for limited access only." + // + // This is good enough for us. + + const auto authStatus = [PHPhotoLibrary authorizationStatus]; + if (authStatus == PHAuthorizationStatusAuthorized) { + showImagePickerDialog_helper(parent); + } else if (authStatus == PHAuthorizationStatusNotDetermined) { + QPointer<QWindow> winGuard(parent); + QPointer<QIOSFileDialog> thisGuard(this); + [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (status == PHAuthorizationStatusAuthorized) { + if (thisGuard && winGuard) + thisGuard->showImagePickerDialog_helper(winGuard); + + } else if (thisGuard) { + emit thisGuard->reject(); + } + }); + }]; + } else { + // Treat 'Limited' (we don't know how to deal with anyway) and 'Denied' as errors. + // FIXME: logging category? + qWarning() << "QIOSFileDialog: insufficient permission, cannot pick images"; + return false; + } return true; } @@ -79,8 +123,7 @@ bool QIOSFileDialog::showNativeDocumentPickerDialog(QWindow *parent) #ifndef Q_OS_TVOS m_viewController = [[QIOSDocumentPickerController alloc] initWithQIOSFileDialog:this]; - UIWindow *window = parent ? reinterpret_cast<UIView *>(parent->winId()).window - : qt_apple_sharedApplication().keyWindow; + UIWindow *window = presentationWindow(parent); [window.rootViewController presentViewController:m_viewController animated:YES completion:nil]; return true; |