blob: fca0432426eacbb590b5f10d8024c8fb7525a284 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
// Copyright (C) 2020 Harald Meyer.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#import <UIKit/UIKit.h>
#import <MobileCoreServices/MobileCoreServices.h>
#include "qiosdocumentpickercontroller.h"
@implementation QIOSDocumentPickerController {
QIOSFileDialog *m_fileDialog;
}
- (instancetype)initWithQIOSFileDialog:(QIOSFileDialog *)fileDialog
{
NSMutableArray <UTType *> *docTypes = [[[NSMutableArray alloc] init] autorelease];
QStringList nameFilters = fileDialog->options()->nameFilters();
if (!nameFilters.isEmpty() && (fileDialog->options()->fileMode() != QFileDialogOptions::Directory
|| fileDialog->options()->fileMode() != QFileDialogOptions::DirectoryOnly))
{
QStringList results;
for (const QString &filter : nameFilters)
results.append(QPlatformFileDialogHelper::cleanFilterList(filter));
docTypes = [self computeAllowedFileTypes:results];
}
if (!docTypes.count) {
switch (fileDialog->options()->fileMode()) {
case QFileDialogOptions::AnyFile:
case QFileDialogOptions::ExistingFile:
case QFileDialogOptions::ExistingFiles:
[docTypes addObject:[UTType typeWithIdentifier:(__bridge NSString *)UTTypeContent]];
[docTypes addObject:[UTType typeWithIdentifier:(__bridge NSString *)UTTypeItem]];
[docTypes addObject:[UTType typeWithIdentifier:(__bridge NSString *)UTTypeData]];
break;
// Showing files is not supported in Directory mode in iOS
case QFileDialogOptions::Directory:
case QFileDialogOptions::DirectoryOnly:
[docTypes addObject:[UTType typeWithIdentifier:(__bridge NSString *)UTTypeFolder]];
break;
}
}
if (self = [super initForOpeningContentTypes:docTypes]) {
m_fileDialog = fileDialog;
self.modalPresentationStyle = UIModalPresentationFormSheet;
self.delegate = self;
self.presentationController.delegate = self;
if (m_fileDialog->options()->fileMode() == QFileDialogOptions::ExistingFiles)
self.allowsMultipleSelection = YES;
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();
}
- (void)presentationControllerDidDismiss:(UIPresentationController *)presentationController
{
Q_UNUSED(presentationController);
// "Called on the delegate when the user has taken action to dismiss the
// presentation successfully, after all animations are finished.
// This is not called if the presentation is dismissed programmatically."
// So if document picker's view was dismissed, for example by swiping it away,
// we got this method called. But not if the dialog was cancelled or a file
// was selected.
emit m_fileDialog->reject();
}
- (NSMutableArray<UTType*>*)computeAllowedFileTypes:(QStringList)filters
{
QStringList fileTypes;
for (const QString &filter : filters) {
if (filter == (QLatin1String("*")))
continue;
if (filter.contains(u'?'))
continue;
if (filter.count(u'*') != 1)
continue;
auto extensions = filter.split('.', Qt::SkipEmptyParts);
fileTypes += extensions.last();
}
NSMutableArray<UTType *> *result = [NSMutableArray<UTType *> arrayWithCapacity:fileTypes.size()];
for (const QString &string : fileTypes)
[result addObject:[UTType typeWithFilenameExtension:string.toNSString()]];
return result;
}
@end
|