diff options
Diffstat (limited to 'Map')
| -rw-r--r-- | Map/Localizable.xcstrings | 11 | ||||
| -rw-r--r-- | Map/Presentation/Commands/MapCommands.swift | 100 |
2 files changed, 107 insertions, 4 deletions
diff --git a/Map/Localizable.xcstrings b/Map/Localizable.xcstrings index 73a58dd..27ea1a0 100644 --- a/Map/Localizable.xcstrings +++ b/Map/Localizable.xcstrings @@ -37,6 +37,17 @@ } } }, + "commands.file.export.format" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Format:" + } + } + } + }, "commands.file.export.panel.content" : { "extractionState" : "manual", "localizations" : { diff --git a/Map/Presentation/Commands/MapCommands.swift b/Map/Presentation/Commands/MapCommands.swift index baf69ad..bcdfd1f 100644 --- a/Map/Presentation/Commands/MapCommands.swift +++ b/Map/Presentation/Commands/MapCommands.swift @@ -13,6 +13,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see https://map.tranquil.systems. import SwiftUI +import UniformTypeIdentifiers struct MapCommands: Commands { @@ -62,20 +63,111 @@ struct MapCommands: Commands { let filename = url?.deletingPathExtension().lastPathComponent ?? "Untitled" + // Create format selection accessory view controller + @MainActor + class ExportAccessoryViewController: NSViewController { + var formatPopup: NSPopUpButton! + + let savePanel: NSSavePanel + let formats: [(String, NSBitmapImageRep.FileType, UTType, String)] + let baseFilename: String + + init( + savePanel: NSSavePanel, + formats: [(String, NSBitmapImageRep.FileType, UTType, String)], baseFilename: String + ) { + self.savePanel = savePanel + self.formats = formats + self.baseFilename = baseFilename + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func loadView() { + let view = NSView(frame: NSRect(x: 0, y: 0, width: 300, height: 30)) + + let label = NSTextField( + labelWithString: String(localized: "commands.file.export.format")) + label.frame = NSRect(x: 10, y: 8, width: 45, height: 17) + + formatPopup = NSPopUpButton( + frame: NSRect(x: 60, y: 5, width: 120, height: 20), pullsDown: false) + formatPopup.autoenablesItems = false + + for (name, _, _, _) in formats { + formatPopup.addItem(withTitle: name) + } + + for item in formatPopup.itemArray { + item.isEnabled = true + } + + // Restore last selected format + let lastSelectedFormat = UserDefaults.standard.integer(forKey: "lastExportFormat") + let validIndex = min(max(lastSelectedFormat, 0), formats.count - 1) + formatPopup.selectItem(at: validIndex) + + formatPopup.target = self + formatPopup.action = #selector(formatChanged(_:)) + + view.addSubview(label) + view.addSubview(formatPopup) + self.view = view + } + + @objc func formatChanged(_ sender: NSPopUpButton) { + let selectedIndex = sender.indexOfSelectedItem + let selectedFormat = formats[selectedIndex] + + // Update allowed content types + savePanel.allowedContentTypes = [selectedFormat.2] + + // Save the selection for next time + UserDefaults.standard.set(selectedIndex, forKey: "lastExportFormat") + } + } + + // Add format options + let formats: [(String, NSBitmapImageRep.FileType, UTType, String)] = [ + ("PNG", .png, .png, "png"), + ("JPEG", .jpeg, .jpeg, "jpg"), + ("TIFF", .tiff, .tiff, "tiff"), + ("BMP", .bmp, .bmp, "bmp"), + ("GIF", .gif, .gif, "gif"), + ] + let savePanel = NSSavePanel() - savePanel.allowedContentTypes = [.png] + + // Set initial content type based on last selection + let lastSelectedFormat = UserDefaults.standard.integer(forKey: "lastExportFormat") + let validIndex = min(max(lastSelectedFormat, 0), formats.count - 1) + savePanel.allowedContentTypes = [formats[validIndex].2] + savePanel.canCreateDirectories = true savePanel.isExtensionHidden = false savePanel.title = String(localized: "commands.file.export.panel.title \(filename)") savePanel.message = String(localized: "commands.file.export.panel.content") - savePanel.nameFieldStringValue = "\(filename).png" + savePanel.nameFieldStringValue = "\(filename)" + + let accessoryController = ExportAccessoryViewController( + savePanel: savePanel, formats: formats, baseFilename: filename) + savePanel.accessoryView = accessoryController.view + savePanel.begin { result in if result == .OK, let url = savePanel.url { if let tiffRepresentation = image.tiffRepresentation { let bitmapImage = NSBitmapImageRep(data: tiffRepresentation) - let pngData = bitmapImage?.representation(using: .png, properties: [:]) + let selectedFormat = formats[accessoryController.formatPopup.indexOfSelectedItem] + + // Generate data based on selected format + let imageData = bitmapImage?.representation( + using: selectedFormat.1, properties: [:]) + do { - try pngData?.write(to: url) + try imageData?.write(to: url) } catch { return } |