#include "common.h" #include "INSWindowHolder.h" #import class SystemDialogs : public ComSingleObject { public: FORWARD_IUNKNOWN() virtual void SelectFolderDialog (IAvnWindow* parentWindowHandle, IAvnSystemDialogEvents* events, bool allowMultiple, const char* title, const char* initialDirectory) override { @autoreleasepool { auto panel = [NSOpenPanel openPanel]; panel.allowsMultipleSelection = allowMultiple; panel.canChooseDirectories = true; panel.canCreateDirectories = true; panel.canChooseFiles = false; if(title != nullptr) { panel.message = [NSString stringWithUTF8String:title]; panel.title = [NSString stringWithUTF8String:title]; } if(initialDirectory != nullptr) { auto directoryString = [NSString stringWithUTF8String:initialDirectory]; panel.directoryURL = [NSURL fileURLWithPath:directoryString]; } auto handler = ^(NSModalResponse result) { if(result == NSFileHandlingPanelOKButton) { auto urls = [panel URLs]; if(urls.count > 0) { void* strings[urls.count]; for(int i = 0; i < urls.count; i++) { auto url = [urls objectAtIndex:i]; auto string = [url path]; strings[i] = (void*)[string UTF8String]; } events->OnCompleted((int)urls.count, &strings[0]); [panel orderOut:panel]; if(parentWindowHandle != nullptr) { auto windowHolder = dynamic_cast(parentWindowHandle); [windowHolder->GetNSWindow() makeKeyAndOrderFront:windowHolder->GetNSWindow()]; } return; } } events->OnCompleted(0, nullptr); }; if(parentWindowHandle != nullptr) { auto windowBase = dynamic_cast(parentWindowHandle); [panel beginSheetModalForWindow:windowBase->GetNSWindow() completionHandler:handler]; } else { [panel beginWithCompletionHandler: handler]; } } } virtual void OpenFileDialog (IAvnWindow* parentWindowHandle, IAvnSystemDialogEvents* events, bool allowMultiple, const char* title, const char* initialDirectory, const char* initialFile, const char* filters) override { @autoreleasepool { auto panel = [NSOpenPanel openPanel]; panel.allowsMultipleSelection = allowMultiple; if(title != nullptr) { panel.message = [NSString stringWithUTF8String:title]; panel.title = [NSString stringWithUTF8String:title]; } if(initialDirectory != nullptr) { auto directoryString = [NSString stringWithUTF8String:initialDirectory]; panel.directoryURL = [NSURL fileURLWithPath:directoryString]; } if(initialFile != nullptr) { panel.nameFieldStringValue = [NSString stringWithUTF8String:initialFile]; } if(filters != nullptr) { auto filtersString = [NSString stringWithUTF8String:filters]; if(filtersString.length > 0) { auto allowedTypes = [filtersString componentsSeparatedByString:@";"]; // Prefer allowedContentTypes if available if (@available(macOS 11.0, *)) { panel.allowedContentTypes = ConvertToUTType(allowedTypes); } else { panel.allowedFileTypes = allowedTypes; } } } auto handler = ^(NSModalResponse result) { if(result == NSFileHandlingPanelOKButton) { auto urls = [panel URLs]; if(urls.count > 0) { void* strings[urls.count]; for(int i = 0; i < urls.count; i++) { auto url = [urls objectAtIndex:i]; auto string = [url path]; strings[i] = (void*)[string UTF8String]; } events->OnCompleted((int)urls.count, &strings[0]); [panel orderOut:panel]; if(parentWindowHandle != nullptr) { auto windowHolder = dynamic_cast(parentWindowHandle); [windowHolder->GetNSWindow() makeKeyAndOrderFront:windowHolder->GetNSWindow()]; } return; } } events->OnCompleted(0, nullptr); }; if(parentWindowHandle != nullptr) { auto windowHolder = dynamic_cast(parentWindowHandle); [panel beginSheetModalForWindow:windowHolder->GetNSWindow() completionHandler:handler]; } else { [panel beginWithCompletionHandler: handler]; } } } virtual void SaveFileDialog (IAvnWindow* parentWindowHandle, IAvnSystemDialogEvents* events, const char* title, const char* initialDirectory, const char* initialFile, const char* filters) override { @autoreleasepool { auto panel = [NSSavePanel savePanel]; if(title != nullptr) { panel.message = [NSString stringWithUTF8String:title]; panel.title = [NSString stringWithUTF8String:title]; } if(initialDirectory != nullptr) { auto directoryString = [NSString stringWithUTF8String:initialDirectory]; panel.directoryURL = [NSURL fileURLWithPath:directoryString]; } if(initialFile != nullptr) { panel.nameFieldStringValue = [NSString stringWithUTF8String:initialFile]; } if(filters != nullptr) { auto filtersString = [NSString stringWithUTF8String:filters]; if(filtersString.length > 0) { auto allowedTypes = [filtersString componentsSeparatedByString:@";"]; // Prefer allowedContentTypes if available if (@available(macOS 11.0, *)) { panel.allowedContentTypes = ConvertToUTType(allowedTypes); } else { panel.allowedFileTypes = allowedTypes; } panel.allowsOtherFileTypes = false; panel.extensionHidden = false; } } auto handler = ^(NSModalResponse result) { if(result == NSFileHandlingPanelOKButton) { void* strings[1]; auto url = [panel URL]; auto string = [url path]; strings[0] = (void*)[string UTF8String]; events->OnCompleted(1, &strings[0]); [panel orderOut:panel]; if(parentWindowHandle != nullptr) { auto windowHolder = dynamic_cast(parentWindowHandle); [windowHolder->GetNSWindow() makeKeyAndOrderFront:windowHolder->GetNSWindow()]; } return; } events->OnCompleted(0, nullptr); }; if(parentWindowHandle != nullptr) { auto windowBase = dynamic_cast(parentWindowHandle); [panel beginSheetModalForWindow:windowBase->GetNSWindow() completionHandler:handler]; } else { [panel beginWithCompletionHandler: handler]; } } } private: NSMutableArray* ConvertToUTType(NSArray* allowedTypes) { auto originalCount = [allowedTypes count]; auto mapped = [[NSMutableArray alloc] init]; if (@available(macOS 11.0, *)) { for (int i = 0; i < originalCount; i++) { auto utTypeStr = allowedTypes[i]; auto utType = [UTType typeWithIdentifier:utTypeStr]; if (utType == nil) { utType = [UTType typeWithMIMEType:utTypeStr]; } if (utType != nil) { [mapped addObject:utType]; } } } return mapped; } }; extern IAvnSystemDialogs* CreateSystemDialogs() { return new SystemDialogs(); }