diff --git a/UniWinC/Assets/Kirurobo/UniWindowController/Runtime/Plugins/MacOS/LibUniWinC.bundle/Contents/MacOS/LibUniWinC b/UniWinC/Assets/Kirurobo/UniWindowController/Runtime/Plugins/MacOS/LibUniWinC.bundle/Contents/MacOS/LibUniWinC index b6ca6ef..7ea2881 100755 Binary files a/UniWinC/Assets/Kirurobo/UniWindowController/Runtime/Plugins/MacOS/LibUniWinC.bundle/Contents/MacOS/LibUniWinC and b/UniWinC/Assets/Kirurobo/UniWindowController/Runtime/Plugins/MacOS/LibUniWinC.bundle/Contents/MacOS/LibUniWinC differ diff --git a/UniWinC/Assets/Kirurobo/UniWindowController/Runtime/Scripts/LowLevel/UniWinCore.cs b/UniWinC/Assets/Kirurobo/UniWindowController/Runtime/Scripts/LowLevel/UniWinCore.cs index cbdeab7..d006e64 100644 --- a/UniWinC/Assets/Kirurobo/UniWindowController/Runtime/Scripts/LowLevel/UniWinCore.cs +++ b/UniWinC/Assets/Kirurobo/UniWindowController/Runtime/Scripts/LowLevel/UniWinCore.cs @@ -11,6 +11,7 @@ using System.Runtime.InteropServices; using AOT; using Kirurobo; using UnityEngine; +using System.Text; #if UNITY_EDITOR using UnityEditor; #endif @@ -298,8 +299,9 @@ namespace Kirurobo private static void _dropFilesCallback([MarshalAs(UnmanagedType.LPWStr)] string paths) { // LF 区切りで届いた文字列を分割してパスの配列に直す - char[] delimiters = { '\n', '\r', '\t', '\0' }; - string[] files = paths.Split(delimiters).Where(s => s != "").ToArray(); + //char[] delimiters = { '\n', '\0' }; + //string[] files = paths.Split(delimiters).Where(s => s != "").ToArray(); + string[] files = parsePaths(paths); if (files.Length > 0) { @@ -319,8 +321,9 @@ namespace Kirurobo private static void _openFilesCallback([MarshalAs(UnmanagedType.LPWStr)] string paths) { // LF 区切りで届いた文字列を分割してパスの配列に直す - char[] delimiters = { '\n', '\r', '\t', '\0' }; - string[] files = paths.Split(delimiters).Where(s => s != "").ToArray(); + //char[] delimiters = { '\n', '\0' }; + //string[] files = paths.Split(delimiters).Where(s => s != "").ToArray(); + string[] files = parsePaths(paths); if (files.Length > 0) { @@ -331,6 +334,62 @@ namespace Kirurobo } } + /// + /// ダブルクオーテーション囲み、LF(またはnull)区切りの文字列を配列に直して返す + /// + /// + /// + private static string[] parsePaths(string text) + { + System.Collections.Generic.List list = new System.Collections.Generic.List(); + bool inEscaped = false; + int len = text.Length; + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < len; i++) + { + char c = text[i]; + if (c == '"') + { + if (inEscaped) + { + if (((i + 1) < len) && text[i + 1] == '"') + { + i++; + sb.Append(c); // 連続ダブルクォーテーションは1つのダブルクオーテーションとする + continue; + } + } + inEscaped = !inEscaped; // 連続でなければ囲み内か否かの切り替え + } else if (c == '\n') { + if (inEscaped) + { + // 囲み内ならパスの一部とする + sb.Append(c); + } else + { + // 囲み内でなければ、区切りとして、次のパスに移る + list.Add(sb.ToString()); + sb.Clear(); + } + } else if (c == '\0') { + // ヌル文字は、常に区切りとして、次のパスに移る + list.Add(sb.ToString()); + sb.Clear(); + } else + { + sb.Append(c); + } + } + if (sb.Length > 0) + { + list.Add(sb.ToString()); + } + + // 空文字列の要素は除去 + list.RemoveAll(v => v.Length == 0); + return list.ToArray(); + } + #endregion #region Find, attach or detach diff --git a/Xcode/LibUniWinC/LibUniWinC.mm b/Xcode/LibUniWinC/LibUniWinC.mm index 7dcadeb..ae0b725 100644 --- a/Xcode/LibUniWinC/LibUniWinC.mm +++ b/Xcode/LibUniWinC/LibUniWinC.mm @@ -132,6 +132,8 @@ UNIWINC_EXPORT BOOL UnregisterWindowStyleChangedCallback() { return [LibUniWinC unregisterWindowStyleChangedCallback]; } +// コールバックにファイルはダブルクオーテーションで囲まれ改行区切りとなった文字列で渡ります。 +// e.g. "/Dir/File1.txt"\n"/Dir/File2.txt"\n"/Dir/File""3"".txt"\n UNIWINC_EXPORT BOOL RegisterDropFilesCallback(StringCallback callback) { return [LibUniWinC registerDropFilesCallbackWithCallback: callback]; } @@ -140,6 +142,10 @@ UNIWINC_EXPORT BOOL UnregisterDropFilesCallback() { return [LibUniWinC unregisterDropFilesCallback]; } +// コールバックに複数パスがダブルクオーテーションで囲まれ改行区切りとなった文字列で渡ります。 +// パスにダブルクオーテーションが含まれる場合は連続ダブルクォーテーションになります。 +// e.g. "/Dir/File1.txt"\n"/Dir/File2.txt"\n"/Dir/File""3"".txt"\n +// ファイル選択キャンセル時には空文字列が渡されます UNIWINC_EXPORT BOOL RegisterOpenFilesCallback(StringCallback callback) { return [LibUniWinC registerOpenFilesCallbackWithCallback: callback]; } diff --git a/Xcode/LibUniWinC/LibUniWinC.swift b/Xcode/LibUniWinC/LibUniWinC.swift index a517efb..08112d0 100644 --- a/Xcode/LibUniWinC/LibUniWinC.swift +++ b/Xcode/LibUniWinC/LibUniWinC.swift @@ -877,13 +877,18 @@ public class LibUniWinC : NSObject { // Make new-line separated string var text: String = "" for url in openFilePanel.urls { - text += url.path + "\n" + text += "\"" + url.path.replacingOccurrences(of: "\"", with: "\"\"") + "\"\n" + //text += '"' + url.path + '"' + "\n" } // Run callback if (callStringCallback(callback: openFilesCallback, text: text)) {} + return } } + + // Canceled or failed + if (callStringCallback(callback: openFilesCallback, text: "")) {} } } diff --git a/Xcode/LibUniWinC/OverlayView.swift b/Xcode/LibUniWinC/OverlayView.swift index 9c67281..cf589c6 100644 --- a/Xcode/LibUniWinC/OverlayView.swift +++ b/Xcode/LibUniWinC/OverlayView.swift @@ -87,16 +87,20 @@ class OverlayView: NSView { guard let urls = sender.draggingPasteboard.propertyList( forType: NSPasteboard.PasteboardType(rawValue: "NSFilenamesPboardType") - ) as? NSArray + ) as? [String] else { return false } // Make new-line separated string - let files: String = urls.componentsJoined(by: "\n") + //let text: String = urls.componentsJoined(by: "\n") + var text: String = "" + for url in urls { + text += "\"" + url.replacingOccurrences(of: "\"", with: "\"\"") + "\"\n" + } // Do callback - return LibUniWinC.callStringCallback(callback: LibUniWinC.dropFilesCallback, text: files) + return LibUniWinC.callStringCallback(callback: LibUniWinC.dropFilesCallback, text: text) } override func draw(_ dirtyRect: NSRect) {