spiegel-keyman/mac/KeymanSettings/Sources/Model/Keyboard.swift
Shawn Schantz bb816a1335
Some checks failed
Keyman Build Summary / Summarize build status checks (push) Has been cancelled
feat(mac): display packages and keyboard list view
added buttons for removal of packages
and toggle for disabling of keyboard
not remotely final but mostly for ensuring that
we can bind to the data model and respond to updates
2026-04-02 14:01:11 -04:00

97 lines
3.2 KiB
Swift

/*
* Keyman is copyright (C) SIL Global. MIT License.
*
* Created by Shawn Schantz on 2026-02-24
*
* Wrapper object that represents a Keyman keyboard as loaded from a .KMP file
* Mostly immutable, but can be marked as enabled/disabled
*
*/
import Foundation
import AppKit
public class Keyboard: Identifiable, Hashable, Equatable {
public var id = UUID()
public var enabled: Bool
public var name: String
public var keyboardId: String
// the directory we are reading the keyboard from
public var keyboardDirectoryUrl: URL
// the URL of the .kmx file for the package
public let kmxFileUrl: URL
// the UserDefaults key for this package, used for the selected Keyboard and active keyboards
// the key is in the form "/[package directory]/[package name].kmx"
// for example, "/khmer_angkor/khmer_angkor.kmx"
public let keyboardSettingsKey: String
public init(keyboardSource: KeyboardSource, directoryUrl: URL) {
self.enabled = true
self.name = keyboardSource.name
self.keyboardId = keyboardSource.id
self.keyboardDirectoryUrl = directoryUrl
self.kmxFileUrl = Keyboard.deriveKmxFileUrl(from: self.keyboardDirectoryUrl, keyboardId: self.keyboardId)
self.keyboardSettingsKey = Keyboard.deriveKeyboardSettingsKey(from: self.keyboardDirectoryUrl, keyboardId: self.keyboardId)
// ConfigLogger.shared.testLogger.debug("keyboard created for: \(keyboardSource.id)")
print("keyboard created for: \(keyboardSource.id) \r with kmxFileUrl: \(self.kmxFileUrl) \r and settingsKey: \(self.keyboardSettingsKey)")
}
public static func == (lhs: Keyboard, rhs: Keyboard) -> Bool {
return lhs.keyboardId == rhs.keyboardId && lhs.enabled == rhs.enabled
}
public func hash(into hasher: inout Hasher) {
hasher.combine(keyboardId)
}
static func deriveKmxFileUrl(from keyboardDirectory: URL, keyboardId: String) -> URL {
return keyboardDirectory.appendingPathComponent("\(keyboardId).kmx")
}
static func deriveKeyboardSettingsKey(from keyboardDirectory: URL, keyboardId: String) -> String {
// get parent directory
let parentDirectoryName = keyboardDirectory.lastPathComponent
// get filename from keyboardId
let kmxFilename = "\(keyboardId).kmx"
let settingsKey = "/\(parentDirectoryName)/\(kmxFilename)"
print("settingsKey: \(settingsKey)")
return settingsKey
}
// TODO: throw/handle error if no kmx file found in directory
public func validateKmxFile() -> Bool {
let fileManager = FileManager.default
if fileManager.fileExists(atPath: self.kmxFileUrl.path) {
return true
} else {
print(" *** Error: could not find kmx file \(self.kmxFileUrl.path)")
return false
}
}
public func findKmxFile(in keyboardDirectoryUrl: URL) -> URL? {
var kmxFileUrl: URL? = nil
let fileManager = FileManager.default
do {
let fileURLs = try fileManager.contentsOfDirectory(at: keyboardDirectoryUrl, includingPropertiesForKeys: nil)
let filteredFiles = fileURLs.filter { $0.pathExtension == "kmx" }
if (!filteredFiles.isEmpty) {
kmxFileUrl = filteredFiles.first!
}
} catch {
print("Error reading directory: \(error)")
}
return kmxFileUrl;
}
}