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 \
|
qiosmenu.mm \
|
||||||
qiosfiledialog.mm \
|
qiosfiledialog.mm \
|
||||||
qiosmessagedialog.mm \
|
qiosmessagedialog.mm \
|
||||||
qiostextinputoverlay.mm
|
qiostextinputoverlay.mm \
|
||||||
|
qiosdocumentpickercontroller.mm
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
qiosclipboard.h \
|
qiosclipboard.h \
|
||||||
qiosmenu.h \
|
qiosmenu.h \
|
||||||
qiosfiledialog.h \
|
qiosfiledialog.h \
|
||||||
qiosmessagedialog.h \
|
qiosmessagedialog.h \
|
||||||
qiostextinputoverlay.h
|
qiostextinputoverlay.h \
|
||||||
|
qiosdocumentpickercontroller.h
|
||||||
}
|
}
|
||||||
|
|
||||||
OTHER_FILES = \
|
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 {}
|
void selectNameFilter(const QString &) override {}
|
||||||
QString selectedNameFilter() const override { return QString(); }
|
QString selectedNameFilter() const override { return QString(); }
|
||||||
|
|
||||||
void selectedFilesChanged(QList<QUrl> selection);
|
void selectedFilesChanged(const QList<QUrl> &selection);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QUrl m_directory;
|
QUrl m_directory;
|
||||||
@ -74,6 +74,7 @@ private:
|
|||||||
UIViewController *m_viewController;
|
UIViewController *m_viewController;
|
||||||
|
|
||||||
bool showImagePickerDialog(QWindow *parent);
|
bool showImagePickerDialog(QWindow *parent);
|
||||||
|
bool showNativeDocumentPickerDialog(QWindow *parent);
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
#include "qiosfiledialog.h"
|
#include "qiosfiledialog.h"
|
||||||
#include "qiosintegration.h"
|
#include "qiosintegration.h"
|
||||||
#include "qiosoptionalplugininterface.h"
|
#include "qiosoptionalplugininterface.h"
|
||||||
|
#include "qiosdocumentpickercontroller.h"
|
||||||
|
|
||||||
QIOSFileDialog::QIOSFileDialog()
|
QIOSFileDialog::QIOSFileDialog()
|
||||||
: m_viewController(nullptr)
|
: m_viewController(nullptr)
|
||||||
@ -72,8 +73,12 @@ bool QIOSFileDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality window
|
|||||||
bool acceptOpen = options()->acceptMode() == QFileDialogOptions::AcceptOpen;
|
bool acceptOpen = options()->acceptMode() == QFileDialogOptions::AcceptOpen;
|
||||||
QString directory = options()->initialDirectory().toLocalFile();
|
QString directory = options()->initialDirectory().toLocalFile();
|
||||||
|
|
||||||
if (acceptOpen && directory.startsWith(QLatin1String("assets-library:")))
|
if (acceptOpen) {
|
||||||
return showImagePickerDialog(parent);
|
if (directory.startsWith(QLatin1String("assets-library:")))
|
||||||
|
return showImagePickerDialog(parent);
|
||||||
|
else
|
||||||
|
return showNativeDocumentPickerDialog(parent);
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -102,6 +107,25 @@ bool QIOSFileDialog::showImagePickerDialog(QWindow *parent)
|
|||||||
return true;
|
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()
|
void QIOSFileDialog::hide()
|
||||||
{
|
{
|
||||||
// QFileDialog will remember the last directory set, and open subsequent dialogs in the same
|
// 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;
|
return m_selection;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QIOSFileDialog::selectedFilesChanged(QList<QUrl> selection)
|
void QIOSFileDialog::selectedFilesChanged(const QList<QUrl> &selection)
|
||||||
{
|
{
|
||||||
m_selection = selection;
|
m_selection = selection;
|
||||||
emit filesSelected(m_selection);
|
emit filesSelected(m_selection);
|
||||||
|
Loading…
Reference in New Issue
Block a user