Add native iOS file dialog
This patch adds native iOS file open and directory picking support for the QFileDialog using the iOS UIDocumentPickerViewController class. Change-Id: Ia724a59742650a01c62067aed3477f82ab1fd546 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
parent
395e2d9bc4
commit
91436e2409
@ -57,13 +57,15 @@ HEADERS = \
|
||||
qiosmenu.mm \
|
||||
qiosfiledialog.mm \
|
||||
qiosmessagedialog.mm \
|
||||
qiostextinputoverlay.mm
|
||||
qiostextinputoverlay.mm \
|
||||
qiosdocumentpickercontroller.mm
|
||||
HEADERS += \
|
||||
qiosclipboard.h \
|
||||
qiosmenu.h \
|
||||
qiosfiledialog.h \
|
||||
qiosmessagedialog.h \
|
||||
qiostextinputoverlay.h
|
||||
qiostextinputoverlay.h \
|
||||
qiosdocumentpickercontroller.h
|
||||
}
|
||||
|
||||
OTHER_FILES = \
|
||||
|
46
src/plugins/platforms/ios/qiosdocumentpickercontroller.h
Normal file
46
src/plugins/platforms/ios/qiosdocumentpickercontroller.h
Normal file
@ -0,0 +1,46 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 Harald Meyer.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#include "qiosfiledialog.h"
|
||||
|
||||
@interface QIOSDocumentPickerController : UIDocumentPickerViewController <UIDocumentPickerDelegate, UINavigationControllerDelegate>
|
||||
- (instancetype)initWithQIOSFileDialog:(QIOSFileDialog *)fileDialog;
|
||||
@end
|
103
src/plugins/platforms/ios/qiosdocumentpickercontroller.mm
Normal file
103
src/plugins/platforms/ios/qiosdocumentpickercontroller.mm
Normal file
@ -0,0 +1,103 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 Harald Meyer.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <MobileCoreServices/MobileCoreServices.h>
|
||||
|
||||
#include "qiosdocumentpickercontroller.h"
|
||||
|
||||
@implementation QIOSDocumentPickerController {
|
||||
QIOSFileDialog *m_fileDialog;
|
||||
}
|
||||
|
||||
- (instancetype)initWithQIOSFileDialog:(QIOSFileDialog *)fileDialog
|
||||
{
|
||||
NSMutableArray <NSString *> *docTypes = [[[NSMutableArray alloc] init] autorelease];
|
||||
UIDocumentPickerMode importMode;
|
||||
switch (fileDialog->options()->fileMode()) {
|
||||
case QFileDialogOptions::AnyFile:
|
||||
case QFileDialogOptions::ExistingFile:
|
||||
case QFileDialogOptions::ExistingFiles:
|
||||
[docTypes addObject:(__bridge NSString *)kUTTypeContent];
|
||||
[docTypes addObject:(__bridge NSString *)kUTTypeItem];
|
||||
[docTypes addObject:(__bridge NSString *)kUTTypeData];
|
||||
importMode = UIDocumentPickerModeImport;
|
||||
break;
|
||||
case QFileDialogOptions::Directory:
|
||||
case QFileDialogOptions::DirectoryOnly:
|
||||
// Directory picking is not supported because it requires
|
||||
// special handling not possible with the current QFilePicker
|
||||
// implementation.
|
||||
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
if (self = [super initWithDocumentTypes:docTypes inMode:importMode]) {
|
||||
m_fileDialog = fileDialog;
|
||||
self.modalPresentationStyle = UIModalPresentationFormSheet;
|
||||
self.delegate = self;
|
||||
|
||||
if (m_fileDialog->options()->fileMode() == QFileDialogOptions::ExistingFiles)
|
||||
self.allowsMultipleSelection = YES;
|
||||
|
||||
if (@available(ios 13.0, *))
|
||||
self.directoryURL = m_fileDialog->options()->initialDirectory().toNSURL();
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray <NSURL *>*)urls
|
||||
{
|
||||
Q_UNUSED(controller);
|
||||
|
||||
QList<QUrl> files;
|
||||
for (NSURL* url in urls)
|
||||
files.append(QUrl::fromNSURL(url));
|
||||
|
||||
m_fileDialog->selectedFilesChanged(files);
|
||||
emit m_fileDialog->accept();
|
||||
}
|
||||
|
||||
- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller
|
||||
{
|
||||
Q_UNUSED(controller)
|
||||
emit m_fileDialog->reject();
|
||||
}
|
||||
|
||||
@end
|
@ -65,7 +65,7 @@ public:
|
||||
void selectNameFilter(const QString &) override {}
|
||||
QString selectedNameFilter() const override { return QString(); }
|
||||
|
||||
void selectedFilesChanged(QList<QUrl> selection);
|
||||
void selectedFilesChanged(const QList<QUrl> &selection);
|
||||
|
||||
private:
|
||||
QUrl m_directory;
|
||||
@ -74,6 +74,7 @@ private:
|
||||
UIViewController *m_viewController;
|
||||
|
||||
bool showImagePickerDialog(QWindow *parent);
|
||||
bool showNativeDocumentPickerDialog(QWindow *parent);
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "qiosfiledialog.h"
|
||||
#include "qiosintegration.h"
|
||||
#include "qiosoptionalplugininterface.h"
|
||||
#include "qiosdocumentpickercontroller.h"
|
||||
|
||||
QIOSFileDialog::QIOSFileDialog()
|
||||
: m_viewController(nullptr)
|
||||
@ -72,8 +73,12 @@ bool QIOSFileDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality window
|
||||
bool acceptOpen = options()->acceptMode() == QFileDialogOptions::AcceptOpen;
|
||||
QString directory = options()->initialDirectory().toLocalFile();
|
||||
|
||||
if (acceptOpen && directory.startsWith(QLatin1String("assets-library:")))
|
||||
return showImagePickerDialog(parent);
|
||||
if (acceptOpen) {
|
||||
if (directory.startsWith(QLatin1String("assets-library:")))
|
||||
return showImagePickerDialog(parent);
|
||||
else
|
||||
return showNativeDocumentPickerDialog(parent);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -102,6 +107,25 @@ bool QIOSFileDialog::showImagePickerDialog(QWindow *parent)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QIOSFileDialog::showNativeDocumentPickerDialog(QWindow *parent)
|
||||
{
|
||||
#ifndef Q_OS_TVOS
|
||||
if (options()->fileMode() == QFileDialogOptions::Directory ||
|
||||
options()->fileMode() == QFileDialogOptions::DirectoryOnly)
|
||||
return false;
|
||||
|
||||
m_viewController = [[QIOSDocumentPickerController alloc] initWithQIOSFileDialog:this];
|
||||
|
||||
UIWindow *window = parent ? reinterpret_cast<UIView *>(parent->winId()).window
|
||||
: qt_apple_sharedApplication().keyWindow;
|
||||
[window.rootViewController presentViewController:m_viewController animated:YES completion:nil];
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void QIOSFileDialog::hide()
|
||||
{
|
||||
// QFileDialog will remember the last directory set, and open subsequent dialogs in the same
|
||||
@ -123,7 +147,7 @@ QList<QUrl> QIOSFileDialog::selectedFiles() const
|
||||
return m_selection;
|
||||
}
|
||||
|
||||
void QIOSFileDialog::selectedFilesChanged(QList<QUrl> selection)
|
||||
void QIOSFileDialog::selectedFilesChanged(const QList<QUrl> &selection)
|
||||
{
|
||||
m_selection = selection;
|
||||
emit filesSelected(m_selection);
|
||||
|
Loading…
Reference in New Issue
Block a user