1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-02 00:10:22 +02:00

[launcher][iOS] select directory to copy oh3 files using objc/uikit

This commit is contained in:
Andrey Filipenkov 2024-06-09 18:10:28 +03:00
parent af7357a938
commit e019997bee
4 changed files with 109 additions and 2 deletions

View File

@ -26,6 +26,8 @@ set(launcher_SRCS
if(APPLE_IOS)
list(APPEND launcher_SRCS
ios/launchGame.m
ios/selectdirectory.h
ios/selectdirectory.mm
)
endif()
@ -212,6 +214,10 @@ if(ENABLE_INNOEXTRACT)
endif()
if(APPLE_IOS)
target_link_libraries(vcmilauncher
"-framework UniformTypeIdentifiers"
)
# TODO: remove after switching prebuilt deps to a newer Conan's Qt recipe
if(XCODE_VERSION VERSION_GREATER_EQUAL 14.0)
target_link_libraries(vcmilauncher "-framework IOKit")

View File

@ -26,7 +26,9 @@
#include "cli/extract.hpp"
#endif
#ifdef VCMI_ANDROID
#ifdef VCMI_IOS
#include "ios/selectdirectory.h"
#elif defined(VCMI_ANDROID)
#include <QAndroidJniObject>
#include <QtAndroid>
@ -385,8 +387,15 @@ void FirstLaunchView::copyHeroesData(const QString & path, bool move)
{
QDir sourceRoot{path};
#ifdef VCMI_IOS
// TODO: Qt 6.5 can select directories https://codereview.qt-project.org/c/qt/qtbase/+/446449
SelectDirectory iosDirectorySelector;
if(path.isEmpty())
sourceRoot.setPath(iosDirectorySelector.getExistingDirectory());
#else
if(path.isEmpty())
sourceRoot.setPath(QFileDialog::getExistingDirectory(this, {}, {}, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks));
#endif
if(!sourceRoot.exists())
return;

View File

@ -0,0 +1,20 @@
/*
* selectdirectory.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#include <QString>
class SelectDirectory final
{
public:
~SelectDirectory();
QString getExistingDirectory();
};

View File

@ -0,0 +1,72 @@
/*
* selectdirectory.mm, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "selectdirectory.h"
#include <QEventLoop>
#import <UIKit/UIKit.h>
#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
#import <MobileCoreServices/MobileCoreServices.h>
@interface ObjcDocumentPickerDelegate : NSObject <UIDocumentPickerDelegate>
@property (nonatomic, assign, readonly) QEventLoop & eventLoop;
@property (nonatomic, copy, nullable) NSURL * selectedDirectoryURL;
@end
@implementation ObjcDocumentPickerDelegate
{
QEventLoop _eventLoop;
}
- (QEventLoop &)eventLoop { return _eventLoop; }
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls
{
self.selectedDirectoryURL = urls.firstObject;
_eventLoop.exit();
}
- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller
{
_eventLoop.exit();
}
@end
static ObjcDocumentPickerDelegate * documentPickerDelegate;
SelectDirectory::~SelectDirectory()
{
[documentPickerDelegate.selectedDirectoryURL stopAccessingSecurityScopedResource];
documentPickerDelegate = nil;
}
QString SelectDirectory::getExistingDirectory()
{
documentPickerDelegate = [ObjcDocumentPickerDelegate new];
UIDocumentPickerViewController * documentPickerVc;
if(@available(iOS 14.0, *))
documentPickerVc = [[UIDocumentPickerViewController alloc] initForOpeningContentTypes:@[UTTypeFolder]];
else
documentPickerVc = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[(__bridge NSString *)kUTTypeFolder] inMode:UIDocumentPickerModeOpen];
documentPickerVc.allowsMultipleSelection = NO;
documentPickerVc.delegate = documentPickerDelegate;
[UIApplication.sharedApplication.keyWindow.rootViewController presentViewController:documentPickerVc animated:YES completion:nil];
documentPickerDelegate.eventLoop.exec(QEventLoop::DialogExec);
if(!documentPickerDelegate.selectedDirectoryURL)
return {};
[documentPickerDelegate.selectedDirectoryURL startAccessingSecurityScopedResource];
return QString::fromNSString(documentPickerDelegate.selectedDirectoryURL.path);
}