diff options
| author | Ruben Beltran del Rio <git@r.bdr.sh> | 2025-07-11 14:55:46 +0200 |
|---|---|---|
| committer | Ruben Beltran del Rio <git@r.bdr.sh> | 2025-07-11 14:55:46 +0200 |
| commit | 49766f0c78015831f8be57349317f0d1c8228327 (patch) | |
| tree | 47ceb138008134dc83ad8432c744e3174854cb2c /QuickLook | |
| parent | f8c877e01e6517b13ec085d9d79bf316c7637344 (diff) | |
Add QuickLook settings
Diffstat (limited to 'QuickLook')
| -rw-r--r-- | QuickLook/PreviewViewController.swift | 143 | ||||
| -rw-r--r-- | QuickLook/QuickLook.entitlements | 12 |
2 files changed, 121 insertions, 34 deletions
diff --git a/QuickLook/PreviewViewController.swift b/QuickLook/PreviewViewController.swift index 03efe72..c93b2cb 100644 --- a/QuickLook/PreviewViewController.swift +++ b/QuickLook/PreviewViewController.swift @@ -23,10 +23,12 @@ class PreviewViewController: NSViewController, QLPreviewingController { // Read the .wmap file content let content = try String(contentsOf: url, encoding: .utf8) - // Parse the content to create a ParsedMap - let lexer = Wmap.Lexer(content) - let parser = Wmap.Parser(lexer: lexer) - let parsedMap = parser.parse() + // Get the user's preview style preference from shared UserDefaults + let sharedDefaults = + UserDefaults(suiteName: "group.systems.tranquil.Map") ?? UserDefaults.standard + let previewStyleString = + sharedDefaults.string(forKey: "quickLookPreviewStyle") ?? QuickLookPreviewStyle.map.rawValue + let previewStyle = QuickLookPreviewStyle(rawValue: previewStyleString) ?? .map await MainActor.run { // Clear any existing subviews and force cleanup @@ -39,34 +41,53 @@ class PreviewViewController: NSViewController, QLPreviewingController { // Force memory cleanup autoreleasepool { - // Create the map preview view with error handling - let mapPreview: AnyView - if parsedMap.entities.isEmpty { - // Fallback view for empty or invalid maps - mapPreview = AnyView( - VStack { - Image(systemName: "map") - .font(.system(size: 48)) - .foregroundColor(.gray) - Text("quick_look.empty_map.title") - .font(.Theme.Title.emphasized) - .foregroundColor(.Theme.UI.foreground) - Text("quick_look.empty_map.description") - .font(.Theme.Body.regular) - .foregroundColor(.Theme.UI.foreground) - } - .frame(maxWidth: .infinity, maxHeight: .infinity) - .foregroundColor(.Theme.UI.background) - ) - } else { - // Limit entities for memory efficiency in QuickLook - let limitedEntities = Array(parsedMap.entities.prefix(100)) // Limit to first 100 entities - let limitedMap = Wmap.ParsedMap( - entities: limitedEntities, vertexLabels: parsedMap.vertexLabels) - mapPreview = AnyView(MapPreviewView(parsedMap: limitedMap)) + let previewContent: AnyView + + switch previewStyle { + case .plainText: + previewContent = AnyView(createPlainTextView(content: content)) + + case .highlightedText: + // Parse for syntax highlighting + let lexer = Wmap.Lexer(content) + let parser = Wmap.Parser(lexer: lexer) + let parsedMap = parser.parse() + previewContent = AnyView( + createHighlightedTextView(content: content, parsedMap: parsedMap)) + + case .map: + // Parse the content to create a ParsedMap + let lexer = Wmap.Lexer(content) + let parser = Wmap.Parser(lexer: lexer) + let parsedMap = parser.parse() + + if parsedMap.entities.isEmpty { + // Fallback view for empty or invalid maps + previewContent = AnyView( + VStack { + Image(systemName: "map") + .font(.system(size: 48)) + .foregroundColor(.gray) + Text("quick_look.empty_map.title") + .font(.Theme.Title.emphasized) + .foregroundColor(.Theme.UI.foreground) + Text("quick_look.empty_map.description") + .font(.Theme.Body.regular) + .foregroundColor(.Theme.UI.foreground) + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + .foregroundColor(.Theme.UI.background) + ) + } else { + // Limit entities for memory efficiency in QuickLook + let limitedEntities = Array(parsedMap.entities.prefix(100)) // Limit to first 100 entities + let limitedMap = Wmap.ParsedMap( + entities: limitedEntities, vertexLabels: parsedMap.vertexLabels) + previewContent = AnyView(MapPreviewView(parsedMap: limitedMap)) + } } - let hostingView = NSHostingView(rootView: mapPreview) + let hostingView = NSHostingView(rootView: previewContent) hostingView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(hostingView) @@ -84,6 +105,24 @@ class PreviewViewController: NSViewController, QLPreviewingController { } } + private func createPlainTextView(content: String) -> some View { + ScrollView([.horizontal, .vertical]) { + Text(content) + .font(.monospaced(.body)()) + .multilineTextAlignment(.leading) + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading) + .padding() + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(Color.white) + } + + private func createHighlightedTextView(content: String, parsedMap: Wmap.ParsedMap) -> some View { + QuickLookTextEditor(content: content, parsedMap: parsedMap) + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(Color.white) + } + deinit { // Cleanup when view controller is deallocated view.subviews.forEach { subview in @@ -129,3 +168,47 @@ struct MapPreviewView: View { } } } + +// A read-only text editor for QuickLook that shows syntax highlighting +struct QuickLookTextEditor: NSViewRepresentable { + let content: String + let parsedMap: Wmap.ParsedMap + + func makeNSView(context: Context) -> NSScrollView { + let scrollView = NSTextView.scrollableTextView() + let textView = scrollView.documentView as! NSTextView + + // Configure the scroll view + scrollView.hasVerticalScroller = true + scrollView.hasHorizontalScroller = true + scrollView.autohidesScrollers = false + + // Configure the text view for read-only display + textView.isEditable = false + textView.isSelectable = true + textView.backgroundColor = NSColor.textBackgroundColor + textView.font = NSFont.monospacedSystemFont(ofSize: 13, weight: .regular) + textView.string = content + textView.isVerticallyResizable = true + textView.isHorizontallyResizable = true + textView.textContainer?.widthTracksTextView = false + textView.textContainer?.containerSize = NSSize( + width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude) + + // Apply syntax highlighting + if let textStorage = textView.textStorage { + let syntaxHighlighter = Wmap.SyntaxHighlighter() + syntaxHighlighter.updateSyntaxElements(from: parsedMap) + + // Apply highlighting to the entire text + let fullRange = NSRange(location: 0, length: textStorage.length) + syntaxHighlighter.applySyntaxHighlighting(textStorage: textStorage, range: fullRange) + } + + return scrollView + } + + func updateNSView(_ nsView: NSScrollView, context: Context) { + // No updates needed for read-only view + } +} diff --git a/QuickLook/QuickLook.entitlements b/QuickLook/QuickLook.entitlements index f2ef3ae..8998767 100644 --- a/QuickLook/QuickLook.entitlements +++ b/QuickLook/QuickLook.entitlements @@ -2,9 +2,13 @@ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> - <key>com.apple.security.app-sandbox</key> - <true/> - <key>com.apple.security.files.user-selected.read-only</key> - <true/> + <key>com.apple.security.app-sandbox</key> + <true/> + <key>com.apple.security.application-groups</key> + <array> + <string>group.systems.tranquil.Map</string> + </array> + <key>com.apple.security.files.user-selected.read-only</key> + <true/> </dict> </plist> |