mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-28 02:30:05 +00:00
226 lines
7.9 KiB
Text
226 lines
7.9 KiB
Text
/*
|
|
==============================================================================
|
|
|
|
This file is part of the JUCE library.
|
|
Copyright (c) 2017 - ROLI Ltd.
|
|
|
|
JUCE is an open source library subject to commercial or open-source
|
|
licensing.
|
|
|
|
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
|
|
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
|
|
27th April 2017).
|
|
|
|
End User License Agreement: www.juce.com/juce-5-licence
|
|
Privacy Policy: www.juce.com/juce-5-privacy-policy
|
|
|
|
Or: You may also use this code under the terms of the GPL v3 (see
|
|
www.gnu.org/licenses).
|
|
|
|
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
|
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
|
DISCLAIMED.
|
|
|
|
==============================================================================
|
|
*/
|
|
|
|
namespace juce
|
|
{
|
|
|
|
//==============================================================================
|
|
template <> struct ContainerDeletePolicy<UIDocumentPickerViewController> { static void destroy (NSObject* o) { [o release]; } };
|
|
template <> struct ContainerDeletePolicy<NSObject<UIDocumentPickerDelegate>> { static void destroy (NSObject* o) { [o release]; } };
|
|
|
|
class FileChooser::Native : private Component, public FileChooser::Pimpl
|
|
{
|
|
public:
|
|
Native (FileChooser& fileChooser, int flags)
|
|
: owner (fileChooser)
|
|
{
|
|
static FileChooserDelegateClass cls;
|
|
delegate = [cls.createInstance() init];
|
|
FileChooserDelegateClass::setOwner (delegate, this);
|
|
|
|
auto utTypeArray = createNSArrayFromStringArray (getUTTypesForWildcards (owner.filters));
|
|
|
|
if ((flags & FileBrowserComponent::saveMode) != 0)
|
|
{
|
|
// You must specify the fileWhichShouldBeSaved parameter when using
|
|
// the native save dialog on iOS!
|
|
jassert (owner.fileToSave.existsAsFile());
|
|
|
|
auto url = [[NSURL alloc] initFileURLWithPath:juceStringToNS (owner.fileToSave.getFullPathName())];
|
|
|
|
controller = [[UIDocumentPickerViewController alloc] initWithURL:url
|
|
inMode:UIDocumentPickerModeExportToService];
|
|
[url release];
|
|
}
|
|
else
|
|
{
|
|
controller = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:utTypeArray
|
|
inMode:UIDocumentPickerModeOpen];
|
|
}
|
|
|
|
[controller setDelegate:delegate];
|
|
[controller setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
|
|
|
|
setOpaque (false);
|
|
|
|
auto chooserBounds = Desktop::getInstance().getDisplays().getMainDisplay().userArea;
|
|
setBounds (chooserBounds);
|
|
|
|
setAlwaysOnTop (true);
|
|
addToDesktop (0);
|
|
}
|
|
|
|
~Native()
|
|
{
|
|
exitModalState (0);
|
|
}
|
|
|
|
void launch() override
|
|
{
|
|
enterModalState (true, nullptr, true);
|
|
}
|
|
|
|
void runModally() override
|
|
{
|
|
#if JUCE_MODAL_LOOPS_PERMITTED
|
|
runModalLoop();
|
|
#endif
|
|
}
|
|
|
|
private:
|
|
//==============================================================================
|
|
void parentHierarchyChanged() override
|
|
{
|
|
auto* newPeer = dynamic_cast<UIViewComponentPeer*> (getPeer());
|
|
|
|
if (peer != newPeer)
|
|
{
|
|
peer = newPeer;
|
|
|
|
if (auto* parentController = peer->controller)
|
|
[parentController showViewController:controller sender:parentController];
|
|
|
|
if (peer->view.window != nil)
|
|
peer->view.window.autoresizesSubviews = YES;
|
|
}
|
|
}
|
|
|
|
//==============================================================================
|
|
static StringArray getUTTypesForWildcards (const String& filterWildcards)
|
|
{
|
|
auto filters = StringArray::fromTokens (filterWildcards, ";", "");
|
|
StringArray result;
|
|
|
|
if (! filters.contains ("*") && filters.size() > 0)
|
|
{
|
|
for (auto filter : filters)
|
|
{
|
|
// iOS only supports file extension wild cards
|
|
jassert (filter.upToLastOccurrenceOf (".", true, false) == "*.");
|
|
|
|
auto fileExtension = filter.fromLastOccurrenceOf (".", false, false);
|
|
auto fileExtensionCF = fileExtension.toCFString();
|
|
|
|
auto tag = UTTypeCreatePreferredIdentifierForTag (kUTTagClassFilenameExtension, fileExtensionCF, nullptr);
|
|
|
|
if (tag != nullptr)
|
|
{
|
|
result.add (String::fromCFString (tag));
|
|
CFRelease (tag);
|
|
}
|
|
|
|
CFRelease (fileExtensionCF);
|
|
}
|
|
}
|
|
else
|
|
result.add ("public.data");
|
|
|
|
return result;
|
|
}
|
|
|
|
//==============================================================================
|
|
void didPickDocumentAtURL (NSURL* url)
|
|
{
|
|
Array<URL> chooserResults;
|
|
chooserResults.add (URL (nsStringToJuce ([url absoluteString])));
|
|
|
|
owner.finished (chooserResults, false);
|
|
exitModalState (1);
|
|
}
|
|
|
|
void pickerWasCancelled()
|
|
{
|
|
Array<URL> chooserResults;
|
|
|
|
owner.finished (chooserResults, false);
|
|
exitModalState (0);
|
|
}
|
|
|
|
//==============================================================================
|
|
struct FileChooserDelegateClass : public ObjCClass<NSObject<UIDocumentPickerDelegate>>
|
|
{
|
|
FileChooserDelegateClass() : ObjCClass<NSObject<UIDocumentPickerDelegate>> ("FileChooserDelegate_")
|
|
{
|
|
addIvar<Native*> ("owner");
|
|
|
|
addMethod (@selector (documentPicker:didPickDocumentAtURL:), didPickDocumentAtURL, "v@:@@");
|
|
addMethod (@selector (documentPickerWasCancelled:), documentPickerWasCancelled, "v@:@");
|
|
|
|
addProtocol (@protocol (UIDocumentPickerDelegate));
|
|
|
|
registerClass();
|
|
}
|
|
|
|
static void setOwner (id self, Native* owner) { object_setInstanceVariable (self, "owner", owner); }
|
|
static Native* getOwner (id self) { return getIvar<Native*> (self, "owner"); }
|
|
|
|
//==============================================================================
|
|
static void didPickDocumentAtURL (id self, SEL, UIDocumentPickerViewController*, NSURL* url)
|
|
{
|
|
auto picker = getOwner (self);
|
|
|
|
if (picker != nullptr)
|
|
picker->didPickDocumentAtURL (url);
|
|
}
|
|
|
|
static void documentPickerWasCancelled (id self, SEL, UIDocumentPickerViewController*)
|
|
{
|
|
auto picker = getOwner (self);
|
|
|
|
if (picker != nullptr)
|
|
picker->pickerWasCancelled();
|
|
}
|
|
};
|
|
|
|
//==============================================================================
|
|
FileChooser& owner;
|
|
ScopedPointer<NSObject<UIDocumentPickerDelegate>> delegate;
|
|
ScopedPointer<UIDocumentPickerViewController> controller;
|
|
UIViewComponentPeer* peer = nullptr;
|
|
|
|
static FileChooserDelegateClass fileChooserDelegateClass;
|
|
|
|
//==============================================================================
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Native)
|
|
};
|
|
|
|
//==============================================================================
|
|
bool FileChooser::isPlatformDialogAvailable()
|
|
{
|
|
#if JUCE_DISABLE_NATIVE_FILECHOOSERS
|
|
return false;
|
|
#else
|
|
return [[NSFileManager defaultManager] ubiquityIdentityToken] != nil;
|
|
#endif
|
|
}
|
|
|
|
FileChooser::Pimpl* FileChooser::showPlatformDialog (FileChooser& owner, int flags,
|
|
FilePreviewComponent*)
|
|
{
|
|
return new FileChooser::Native (owner, flags);
|
|
}
|
|
|
|
} // namespace juce
|