diff --git a/Keyboards/KeyboardsBase/InterfaceVariables.swift b/Keyboards/KeyboardsBase/InterfaceVariables.swift index 6e16e3fe..10c74de0 100644 --- a/Keyboards/KeyboardsBase/InterfaceVariables.swift +++ b/Keyboards/KeyboardsBase/InterfaceVariables.swift @@ -159,7 +159,6 @@ func checkLandscapeMode() { // Keyboard language variables. var controllerLanguage = String() -var controllerLanguageAbbr = String() // Dictionary for accessing language abbreviations. let languagesAbbrDict = [ @@ -184,6 +183,13 @@ let languagesStringDict = [ "Swedish": NSLocalizedString("_global.swedish", value: "Swedish", comment: "") ] +func getKeyInDict(givenValue: String, dict: [String: String]) -> String { + for (key, value) in dict where value == givenValue { + return key + } + return "" +} + /// Returns the abbreviation of the language for use in commands. func getControllerLanguageAbbr() -> String { guard let abbreviation = languagesAbbrDict[controllerLanguage] else { @@ -192,6 +198,17 @@ func getControllerLanguageAbbr() -> String { return abbreviation } +func getControllerTranslateLangCode() -> String { + let userDefaults = UserDefaults(suiteName: "group.be.scri.userDefaultsContainer")! + let key = getControllerLanguageAbbr() + "TranslateLanguage" + if let translateLang = userDefaults.string(forKey: key) { + return translateLang + } else { + userDefaults.set("en", forKey: key) + return "en" + } +} + // Dictionary for accessing keyboard abbreviations and layouts. let keyboardLayoutDict: [String: () -> Void] = [ // Layouts for French checked within setFRKeyboardLayout. @@ -214,7 +231,12 @@ func setKeyboard() { /// Sets the keyboard layouts given the chosen keyboard and device type. func setKeyboardLayout() { if commandState == .translate { - setENKeyboardLayout() + let translateLanguage = getKeyInDict(givenValue: getControllerTranslateLangCode(), dict: languagesAbbrDict) + if let setLayoutFxn = keyboardLayoutDict[translateLanguage] { + setLayoutFxn() + } else { + setENKeyboardLayout() + } } else if let setLayoutFxn = keyboardLayoutDict[controllerLanguage] { setLayoutFxn() } diff --git a/Keyboards/KeyboardsBase/KeyboardKeys.swift b/Keyboards/KeyboardsBase/KeyboardKeys.swift index 947cad45..4e48933a 100644 --- a/Keyboards/KeyboardsBase/KeyboardKeys.swift +++ b/Keyboards/KeyboardsBase/KeyboardKeys.swift @@ -210,27 +210,26 @@ class KeyboardKey: UIButton { /// Adjusts the width of a key if it's one of the special characters on the iPhone keyboard. func adjustPhoneKeyWidth() { - if key == "ABC" || key == "АБВ" { + if ["ABC", "АБВ"].contains(key) { layer.setValue(true, forKey: "isSpecial") widthAnchor.constraint(equalToConstant: numSymKeyWidth * 2).isActive = true - } else if key == "delete" - || key == "#+=" - || key == "shift" - || key == "selectKeyboard" { - // Cancel Russian keyboard key resizing if translating as the keyboard is English. - if controllerLanguage == "Russian" - && keyboardState == .letters - && commandState != .translate { + } else if ["delete", "#+=", "shift", "selectKeyboard"].contains(key) { + if keyboardState == .letters + && ( + ( + commandState != .translate + && controllerLanguage == "Russian" + ) || ( + commandState == .translate + && getControllerTranslateLangCode() == "ru" + )) { layer.setValue(true, forKey: "isSpecial") widthAnchor.constraint(equalToConstant: numSymKeyWidth * 1).isActive = true } else { layer.setValue(true, forKey: "isSpecial") widthAnchor.constraint(equalToConstant: numSymKeyWidth * 1.5).isActive = true } - } else if key == "123" - || key == ".?123" - || key == "return" - || key == "hideKeyboard" { + } else if ["123", ".?123", "return", "hideKeyboard"].contains(key) { if row == 2 { layer.setValue(true, forKey: "isSpecial") widthAnchor.constraint(equalToConstant: numSymKeyWidth * 1.5).isActive = true @@ -256,7 +255,7 @@ class KeyboardKey: UIButton { scalarShiftKeyWidth = 1.5 scalarSpecialKeysWidth = 1.0 - if key == "ABC" || key == "АБВ" { + if ["ABC", "АБВ"].contains(key) { layer.setValue(true, forKey: "isSpecial") widthAnchor.constraint(equalToConstant: numSymKeyWidth * 1).isActive = true } else if ["#+=", "selectKeyboard"].contains(key) { @@ -281,15 +280,18 @@ class KeyboardKey: UIButton { layer.setValue(true, forKey: "isSpecial") widthAnchor.constraint(equalToConstant: numSymKeyWidth * scalarReturnKeyWidth).isActive = true } else if ["123", ".?123", "return", "hideKeyboard"].contains(key) { - if key == "return" + if DeviceType.isPad + && key == "return" && ( - controllerLanguage == "English" - || controllerLanguage == "Portuguese" - || controllerLanguage == "Italian" - || commandState == .translate + ( + commandState != .translate + && ["English", "Portuguese", "Italian"].contains(controllerLanguage) + ) || ( + commandState == .translate + && ["en", "pt", "it"].contains(getControllerTranslateLangCode()) + ) ) - && row == 1 - && DeviceType.isPad { + && row == 1 { layer.setValue(true, forKey: "isSpecial") widthAnchor.constraint(equalToConstant: numSymKeyWidth * scalarReturnKeyWidth).isActive = true } else { @@ -300,22 +302,25 @@ class KeyboardKey: UIButton { widthAnchor.constraint(equalToConstant: keyWidth).isActive = true } } else { - if key == "ABC" || key == "АБВ" { + if ["ABC", "АБВ"].contains(key) { layer.setValue(true, forKey: "isSpecial") widthAnchor.constraint(equalToConstant: numSymKeyWidth * 1).isActive = true } else if ["delete", "#+=", "shift", "selectKeyboard", SpecialKeys.indent, SpecialKeys.capsLock].contains(key) { layer.setValue(true, forKey: "isSpecial") widthAnchor.constraint(equalToConstant: numSymKeyWidth * 1).isActive = true } else if ["123", ".?123", "return", "hideKeyboard"].contains(key) { - if key == "return" + if DeviceType.isPad + && key == "return" && ( - controllerLanguage == "English" - || controllerLanguage == "Portuguese" - || controllerLanguage == "Italian" - || commandState == .translate + ( + commandState != .translate + && ["English", "Portuguese", "Italian"].contains(controllerLanguage) + ) || ( + commandState == .translate + && ["en", "pt", "it"].contains(getControllerTranslateLangCode()) + ) ) - && row == 1 - && DeviceType.isPad { + && row == 1 { layer.setValue(true, forKey: "isSpecial") widthAnchor.constraint(equalToConstant: numSymKeyWidth * 1.5).isActive = true } else { diff --git a/Keyboards/KeyboardsBase/KeyboardViewController.swift b/Keyboards/KeyboardsBase/KeyboardViewController.swift index 29038b16..a24c707c 100644 --- a/Keyboards/KeyboardsBase/KeyboardViewController.swift +++ b/Keyboards/KeyboardsBase/KeyboardViewController.swift @@ -1563,7 +1563,7 @@ class KeyboardViewController: UIInputViewController { } else { conjugationToDisplay = "was/were " + conjugationToDisplay } - } else if index == 3 && allConjugations[index] == "presPerfTPS" { + } else if index == 2 && allConjugations[index] == "presPerfTPS" { conjugationToDisplay = "have/" + conjugationToDisplay } else if index == 3 && allConjugations[index] == "presPerfTPSCont" { conjugationToDisplay = "have/" + conjugationToDisplay @@ -1707,27 +1707,35 @@ class KeyboardViewController: UIInputViewController { var leftPadding = CGFloat(0) if DeviceType.isPhone && key == "y" - && ["German", "Swedish"].contains(controllerLanguage) - && commandState != .translate - && disableAccentCharacters != true { + && ( + ( + commandState != .translate + && ["German", "Swedish"].contains(controllerLanguage) + ) || ( + commandState == .translate + && ["de", "sv"].contains(getControllerTranslateLangCode()) + ) + ) + && !disableAccentCharacters { leftPadding = keyWidth / 3 addPadding(to: stackView2, width: leftPadding, key: "y") } if DeviceType.isPhone && key == "a" && ( - controllerLanguage == "English" - || controllerLanguage == "Portuguese" - || controllerLanguage == "Italian" - || commandState == .translate - || ( - ( - controllerLanguage == "German" - || controllerLanguage == "Spanish" - || controllerLanguage == "Swedish" + ( + commandState != .translate + && ( + ["English", "Portuguese", "Italian"].contains(controllerLanguage) + || ( + ["German", "Spanish", "Swedish"].contains(controllerLanguage) + && disableAccentCharacters + ) ) - && disableAccentCharacters == true - )) { + ) || ( + commandState == .translate + && ["en", "pt", "it"].contains(getControllerTranslateLangCode()) + )) { leftPadding = keyWidth / 4 addPadding(to: stackView1, width: leftPadding, key: "a") } @@ -1735,11 +1743,13 @@ class KeyboardViewController: UIInputViewController { && key == "a" && !usingExpandedKeyboard && ( - controllerLanguage == "English" - || controllerLanguage == "Portuguese" - || controllerLanguage == "Italian" - || commandState == .translate - ) { + ( + commandState != .translate + && ["English", "Portuguese", "Italian"].contains(controllerLanguage) + ) || ( + commandState == .translate + && ["en", "pt", "it"].contains(getControllerTranslateLangCode()) + )) { leftPadding = keyWidth / 3 addPadding(to: stackView1, width: leftPadding, key: "a") } @@ -1747,10 +1757,13 @@ class KeyboardViewController: UIInputViewController { && key == "@" && !usingExpandedKeyboard && ( - controllerLanguage == "English" - || controllerLanguage == "Portuguese" - || controllerLanguage == "Italian" - || commandState == .translate) { + ( + commandState != .translate + && ["English", "Portuguese", "Italian"].contains(controllerLanguage) + ) || ( + commandState == .translate + && ["en", "pt", "it"].contains(getControllerTranslateLangCode()) + )) { leftPadding = keyWidth / 3 addPadding(to: stackView1, width: leftPadding, key: "@") } @@ -1758,9 +1771,13 @@ class KeyboardViewController: UIInputViewController { && key == "€" && !usingExpandedKeyboard && ( - controllerLanguage == "English" - || controllerLanguage == "Portuguese" - || commandState == .translate) { + ( + commandState != .translate + && ["English", "Portuguese"].contains(controllerLanguage) + ) || ( + commandState == .translate + && ["en", "pt"].contains(getControllerTranslateLangCode()) + )) { leftPadding = keyWidth / 3 addPadding(to: stackView1, width: leftPadding, key: "€") } @@ -1847,27 +1864,35 @@ class KeyboardViewController: UIInputViewController { var rightPadding = CGFloat(0) if DeviceType.isPhone && key == "m" - && ["German", "Swedish"].contains(controllerLanguage) - && commandState != .translate - && disableAccentCharacters != true { + && ( + ( + commandState != .translate + && ["German", "Swedish"].contains(controllerLanguage) + ) || ( + commandState == .translate + && ["de", "sv"].contains(getControllerTranslateLangCode()) + ) + ) + && !disableAccentCharacters { rightPadding = keyWidth / 3 addPadding(to: stackView2, width: rightPadding, key: "m") } if DeviceType.isPhone && key == "l" && ( - controllerLanguage == "English" - || controllerLanguage == "Portuguese" - || controllerLanguage == "Italian" - || commandState == .translate - || ( - ( - controllerLanguage == "German" - || controllerLanguage == "Spanish" - || controllerLanguage == "Swedish" + ( + commandState != .translate + && ( + ["English", "Portuguese", "Italian"].contains(controllerLanguage) + || ( + ["German", "Spanish", "Swedish"].contains(controllerLanguage) + && disableAccentCharacters + ) ) - && disableAccentCharacters == true - )) { + ) || ( + commandState == .translate + && ["en", "pt", "it"].contains(getControllerTranslateLangCode()) + )) { rightPadding = keyWidth / 4 addPadding(to: stackView1, width: rightPadding, key: "l") } @@ -2348,6 +2373,7 @@ class KeyboardViewController: UIInputViewController { case "Translate": if let selectedText = proxy.selectedText { + commandState = .translate queryWordToTranslate(queriedWordToTranslate: selectedText) if commandState == .invalid { // invalid state diff --git a/Keyboards/KeyboardsBase/LanguageDBManager.swift b/Keyboards/KeyboardsBase/LanguageDBManager.swift index 1aa3e2a4..ff0d5def 100644 --- a/Keyboards/KeyboardsBase/LanguageDBManager.swift +++ b/Keyboards/KeyboardsBase/LanguageDBManager.swift @@ -26,12 +26,12 @@ class LanguageDBManager { private var languageDB: DatabaseQueue? private init() { - languageDB = openDBQueue() + languageDB = openDBQueue(getControllerLanguageAbbr()) } /// Makes a connection to the language database given the value for controllerLanguage. - private func openDBQueue() -> DatabaseQueue { - let dbName = "\(String(describing: get_iso_code(keyboardLanguage: controllerLanguage).uppercased()))LanguageData" + private func openDBQueue(_ langAbbr: String) -> DatabaseQueue { + let dbName = "\(String(describing: langAbbr.uppercased()))LanguageData" let dbResourcePath = Bundle.main.path(forResource: dbName, ofType: "sqlite")! let fileManager = FileManager.default do { @@ -72,10 +72,18 @@ class LanguageDBManager { private func queryDBRow(query: String, outputCols: [String], args: StatementArguments) -> [String] { var outputValues = [String]() do { - try languageDB?.read { db in - if let row = try Row.fetchOne(db, sql: query, arguments: args) { - for col in outputCols { - outputValues.append(row[col]) + if commandState == .translate { + try openDBQueue(getControllerTranslateLangCode()).read { db in + if let row = try Row.fetchOne(db, sql: query, arguments: args) { + outputValues.append(row[outputCols[0]]) + } + } + } else { + try languageDB?.read { db in + if let row = try Row.fetchOne(db, sql: query, arguments: args) { + for col in outputCols { + outputValues.append(row[col]) + } } } } @@ -340,7 +348,7 @@ extension LanguageDBManager { WHERE word = ? """ - let outputCols = ["translation"] + let outputCols = [getControllerLanguageAbbr()] let args = [word] return queryDBRow(query: query, outputCols: outputCols, args: StatementArguments(args)) diff --git a/Keyboards/KeyboardsBase/Utilities.swift b/Keyboards/KeyboardsBase/Utilities.swift index 549bb96f..cdb4deba 100644 --- a/Keyboards/KeyboardsBase/Utilities.swift +++ b/Keyboards/KeyboardsBase/Utilities.swift @@ -17,36 +17,6 @@ * along with this program. If not, see . */ -/// Returns the ISO code given a language. -/// -/// - Parameters -/// - language: the language an ISO code should be returned for. -func get_iso_code(keyboardLanguage: String) -> String { - var iso = "" - switch keyboardLanguage { - case "English": - iso = "en" - case "French": - iso = "fr" - case "German": - iso = "de" - case "Italian": - iso = "it" - case "Portuguese": - iso = "pt" - case "Russian": - iso = "ru" - case "Spanish": - iso = "es" - case "Swedish": - iso = "sv" - default: - break - } - - return iso -} - /// Checks if an extra space is needed in the text field when generated text is inserted func getOptionalSpace() -> String { if proxy.documentContextAfterInput?.first == " " { diff --git a/Keyboards/LanguageKeyboards/English/ENInterfaceVariables.swift b/Keyboards/LanguageKeyboards/English/ENInterfaceVariables.swift index 8cc1be0f..c43ca5cd 100644 --- a/Keyboards/LanguageKeyboards/English/ENInterfaceVariables.swift +++ b/Keyboards/LanguageKeyboards/English/ENInterfaceVariables.swift @@ -228,13 +228,15 @@ func setENKeyboardLayout() { ] translateKeyLbl = "Translate" - translatePrompt = commandPromptSpacing + "Currently not utilized" // "en -› \(getControllerLanguageAbbr()): " - translatePromptAndCursor = translatePrompt // + commandCursor - translatePromptAndPlaceholder = translatePromptAndCursor // + " " + translatePlaceholder + translatePlaceholder = "Enter a word" + translatePrompt = commandPromptSpacing + "en -› \(getControllerLanguageAbbr()): " + translatePromptAndCursor = translatePrompt + commandCursor + translatePromptAndPlaceholder = translatePromptAndCursor + " " + translatePlaceholder translatePromptAndColorPlaceholder = NSMutableAttributedString(string: translatePromptAndPlaceholder) translatePromptAndColorPlaceholder.setColorForText(textForAttribute: translatePlaceholder, withColor: UIColor(cgColor: commandBarPlaceholderColorCG)) conjugateKeyLbl = "Conjugate" + conjugatePlaceholder = "Enter a verb" conjugatePrompt = commandPromptSpacing + "Conjugate: " conjugatePromptAndCursor = conjugatePrompt + commandCursor conjugatePromptAndPlaceholder = conjugatePromptAndCursor + " " + conjugatePlaceholder @@ -242,6 +244,7 @@ func setENKeyboardLayout() { conjugatePromptAndColorPlaceholder.setColorForText(textForAttribute: conjugatePlaceholder, withColor: UIColor(cgColor: commandBarPlaceholderColorCG)) pluralKeyLbl = "Plural" + pluralPlaceholder = "Enter a noun" pluralPrompt = commandPromptSpacing + "Plural: " pluralPromptAndCursor = pluralPrompt + commandCursor pluralPromptAndPlaceholder = pluralPromptAndCursor + " " + pluralPlaceholder diff --git a/Keyboards/LanguageKeyboards/English/ENLanguageData.sqlite b/Keyboards/LanguageKeyboards/English/ENLanguageData.sqlite index 70de6286..769b84a7 100644 Binary files a/Keyboards/LanguageKeyboards/English/ENLanguageData.sqlite and b/Keyboards/LanguageKeyboards/English/ENLanguageData.sqlite differ diff --git a/Keyboards/LanguageKeyboards/French/FRLanguageData.sqlite b/Keyboards/LanguageKeyboards/French/FRLanguageData.sqlite index e52e8e1b..f9fc0056 100644 Binary files a/Keyboards/LanguageKeyboards/French/FRLanguageData.sqlite and b/Keyboards/LanguageKeyboards/French/FRLanguageData.sqlite differ diff --git a/Keyboards/LanguageKeyboards/German/DELanguageData.sqlite b/Keyboards/LanguageKeyboards/German/DELanguageData.sqlite index ba2a1686..ddd63dfa 100644 Binary files a/Keyboards/LanguageKeyboards/German/DELanguageData.sqlite and b/Keyboards/LanguageKeyboards/German/DELanguageData.sqlite differ diff --git a/Keyboards/LanguageKeyboards/Italian/ITLanguageData.sqlite b/Keyboards/LanguageKeyboards/Italian/ITLanguageData.sqlite index 77f0c893..0557d092 100644 Binary files a/Keyboards/LanguageKeyboards/Italian/ITLanguageData.sqlite and b/Keyboards/LanguageKeyboards/Italian/ITLanguageData.sqlite differ diff --git a/Keyboards/LanguageKeyboards/Portuguese/PTLanguageData.sqlite b/Keyboards/LanguageKeyboards/Portuguese/PTLanguageData.sqlite index 971750e0..f801e5c5 100644 Binary files a/Keyboards/LanguageKeyboards/Portuguese/PTLanguageData.sqlite and b/Keyboards/LanguageKeyboards/Portuguese/PTLanguageData.sqlite differ diff --git a/Keyboards/LanguageKeyboards/Russian/RULanguageData.sqlite b/Keyboards/LanguageKeyboards/Russian/RULanguageData.sqlite index 05cca6a4..822d0bf2 100644 Binary files a/Keyboards/LanguageKeyboards/Russian/RULanguageData.sqlite and b/Keyboards/LanguageKeyboards/Russian/RULanguageData.sqlite differ diff --git a/Keyboards/LanguageKeyboards/Spanish/ESLanguageData.sqlite b/Keyboards/LanguageKeyboards/Spanish/ESLanguageData.sqlite index 52c71cf7..cdc04f39 100644 Binary files a/Keyboards/LanguageKeyboards/Spanish/ESLanguageData.sqlite and b/Keyboards/LanguageKeyboards/Spanish/ESLanguageData.sqlite differ diff --git a/Keyboards/LanguageKeyboards/Swedish/SVLanguageData.sqlite b/Keyboards/LanguageKeyboards/Swedish/SVLanguageData.sqlite index 1a51208f..92b7d698 100644 Binary files a/Keyboards/LanguageKeyboards/Swedish/SVLanguageData.sqlite and b/Keyboards/LanguageKeyboards/Swedish/SVLanguageData.sqlite differ diff --git a/Keyboards/LanguageKeyboards/TranslationData.sqlite b/Keyboards/LanguageKeyboards/TranslationData.sqlite new file mode 100644 index 00000000..1dcb60e8 Binary files /dev/null and b/Keyboards/LanguageKeyboards/TranslationData.sqlite differ diff --git a/Scribe.xcodeproj/project.pbxproj b/Scribe.xcodeproj/project.pbxproj index b35e7e1e..4e68b5c6 100644 --- a/Scribe.xcodeproj/project.pbxproj +++ b/Scribe.xcodeproj/project.pbxproj @@ -124,7 +124,90 @@ 38BD214F22D592CA00C6795D /* DEKeyboardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38BD214E22D592CA00C6795D /* DEKeyboardViewController.swift */; }; 38BD215322D592CA00C6795D /* German.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 38BD214C22D592CA00C6795D /* German.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 38DD94F122D6A40000FF8845 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38DD94F022D6A40000FF8845 /* Extensions.swift */; }; + 5A037FDA2C74D6C800D4AADD /* DELanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298129E41B56006B2C81 /* DELanguageData.sqlite */; }; + 5A037FDB2C74D6C900D4AADD /* DELanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298129E41B56006B2C81 /* DELanguageData.sqlite */; }; + 5A037FDC2C74D6CA00D4AADD /* DELanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298129E41B56006B2C81 /* DELanguageData.sqlite */; }; + 5A037FDD2C74D6CA00D4AADD /* DELanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298129E41B56006B2C81 /* DELanguageData.sqlite */; }; + 5A037FDE2C74D6CB00D4AADD /* DELanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298129E41B56006B2C81 /* DELanguageData.sqlite */; }; + 5A037FDF2C74D6CC00D4AADD /* DELanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298129E41B56006B2C81 /* DELanguageData.sqlite */; }; + 5A037FE02C74D6CD00D4AADD /* DELanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298129E41B56006B2C81 /* DELanguageData.sqlite */; }; + 5A037FE12C74D6CD00D4AADD /* DELanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298129E41B56006B2C81 /* DELanguageData.sqlite */; }; + 5A037FE22C74D6CE00D4AADD /* DELanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298129E41B56006B2C81 /* DELanguageData.sqlite */; }; + 5A037FE32C74D6CE00D4AADD /* DELanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298129E41B56006B2C81 /* DELanguageData.sqlite */; }; + 5A037FE42C74D6D400D4AADD /* ENLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = 5A8FFB6E2C5E575B00F4B571 /* ENLanguageData.sqlite */; }; + 5A037FE52C74D6D500D4AADD /* ENLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = 5A8FFB6E2C5E575B00F4B571 /* ENLanguageData.sqlite */; }; + 5A037FE62C74D6D500D4AADD /* ENLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = 5A8FFB6E2C5E575B00F4B571 /* ENLanguageData.sqlite */; }; + 5A037FE72C74D6D600D4AADD /* ENLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = 5A8FFB6E2C5E575B00F4B571 /* ENLanguageData.sqlite */; }; + 5A037FE82C74D6D800D4AADD /* ENLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = 5A8FFB6E2C5E575B00F4B571 /* ENLanguageData.sqlite */; }; + 5A037FE92C74D6D800D4AADD /* ENLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = 5A8FFB6E2C5E575B00F4B571 /* ENLanguageData.sqlite */; }; + 5A037FEA2C74D6D900D4AADD /* ENLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = 5A8FFB6E2C5E575B00F4B571 /* ENLanguageData.sqlite */; }; + 5A037FEB2C74D6DA00D4AADD /* ENLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = 5A8FFB6E2C5E575B00F4B571 /* ENLanguageData.sqlite */; }; + 5A037FEC2C74D6DA00D4AADD /* ENLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = 5A8FFB6E2C5E575B00F4B571 /* ENLanguageData.sqlite */; }; + 5A037FED2C74D6DB00D4AADD /* ENLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = 5A8FFB6E2C5E575B00F4B571 /* ENLanguageData.sqlite */; }; + 5A037FEE2C74D6E200D4AADD /* FRLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E297E29E41B3B006B2C81 /* FRLanguageData.sqlite */; }; + 5A037FEF2C74D6E300D4AADD /* FRLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E297E29E41B3B006B2C81 /* FRLanguageData.sqlite */; }; + 5A037FF02C74D6E500D4AADD /* FRLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E297E29E41B3B006B2C81 /* FRLanguageData.sqlite */; }; + 5A037FF12C74D6E500D4AADD /* FRLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E297E29E41B3B006B2C81 /* FRLanguageData.sqlite */; }; + 5A037FF22C74D6E600D4AADD /* FRLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E297E29E41B3B006B2C81 /* FRLanguageData.sqlite */; }; + 5A037FF32C74D6E800D4AADD /* FRLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E297E29E41B3B006B2C81 /* FRLanguageData.sqlite */; }; + 5A037FF42C74D6E800D4AADD /* FRLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E297E29E41B3B006B2C81 /* FRLanguageData.sqlite */; }; + 5A037FF52C74D6E900D4AADD /* FRLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E297E29E41B3B006B2C81 /* FRLanguageData.sqlite */; }; + 5A037FF62C74D6EA00D4AADD /* FRLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E297E29E41B3B006B2C81 /* FRLanguageData.sqlite */; }; + 5A037FF72C74D6EA00D4AADD /* FRLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E297E29E41B3B006B2C81 /* FRLanguageData.sqlite */; }; + 5A037FF82C74D6FF00D4AADD /* ITLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298329E41B74006B2C81 /* ITLanguageData.sqlite */; }; + 5A037FF92C74D70000D4AADD /* ITLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298329E41B74006B2C81 /* ITLanguageData.sqlite */; }; + 5A037FFA2C74D70100D4AADD /* ITLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298329E41B74006B2C81 /* ITLanguageData.sqlite */; }; + 5A037FFB2C74D70200D4AADD /* ITLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298329E41B74006B2C81 /* ITLanguageData.sqlite */; }; + 5A037FFC2C74D70300D4AADD /* ITLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298329E41B74006B2C81 /* ITLanguageData.sqlite */; }; + 5A037FFD2C74D70400D4AADD /* ITLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298329E41B74006B2C81 /* ITLanguageData.sqlite */; }; + 5A037FFE2C74D70400D4AADD /* ITLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298329E41B74006B2C81 /* ITLanguageData.sqlite */; }; + 5A037FFF2C74D70500D4AADD /* ITLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298329E41B74006B2C81 /* ITLanguageData.sqlite */; }; + 5A0380002C74D70600D4AADD /* ITLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298329E41B74006B2C81 /* ITLanguageData.sqlite */; }; + 5A0380012C74D70700D4AADD /* ITLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298329E41B74006B2C81 /* ITLanguageData.sqlite */; }; + 5A0380022C74D70B00D4AADD /* PTLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298529E41B8F006B2C81 /* PTLanguageData.sqlite */; }; + 5A0380032C74D70C00D4AADD /* PTLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298529E41B8F006B2C81 /* PTLanguageData.sqlite */; }; + 5A0380042C74D70D00D4AADD /* PTLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298529E41B8F006B2C81 /* PTLanguageData.sqlite */; }; + 5A0380052C74D70D00D4AADD /* PTLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298529E41B8F006B2C81 /* PTLanguageData.sqlite */; }; + 5A0380062C74D70E00D4AADD /* PTLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298529E41B8F006B2C81 /* PTLanguageData.sqlite */; }; + 5A0380072C74D70F00D4AADD /* PTLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298529E41B8F006B2C81 /* PTLanguageData.sqlite */; }; + 5A0380082C74D70F00D4AADD /* PTLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298529E41B8F006B2C81 /* PTLanguageData.sqlite */; }; + 5A0380092C74D71100D4AADD /* PTLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298529E41B8F006B2C81 /* PTLanguageData.sqlite */; }; + 5A03800A2C74D71300D4AADD /* PTLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298529E41B8F006B2C81 /* PTLanguageData.sqlite */; }; + 5A03800B2C74D71400D4AADD /* PTLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298529E41B8F006B2C81 /* PTLanguageData.sqlite */; }; + 5A03800C2C74D71900D4AADD /* RULanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298729E41BA1006B2C81 /* RULanguageData.sqlite */; }; + 5A03800D2C74D71A00D4AADD /* RULanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298729E41BA1006B2C81 /* RULanguageData.sqlite */; }; + 5A03800E2C74D71B00D4AADD /* RULanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298729E41BA1006B2C81 /* RULanguageData.sqlite */; }; + 5A03800F2C74D71C00D4AADD /* RULanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298729E41BA1006B2C81 /* RULanguageData.sqlite */; }; + 5A0380102C74D71D00D4AADD /* RULanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298729E41BA1006B2C81 /* RULanguageData.sqlite */; }; + 5A0380112C74D71F00D4AADD /* RULanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298729E41BA1006B2C81 /* RULanguageData.sqlite */; }; + 5A0380122C74D71F00D4AADD /* RULanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298729E41BA1006B2C81 /* RULanguageData.sqlite */; }; + 5A0380132C74D72000D4AADD /* RULanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298729E41BA1006B2C81 /* RULanguageData.sqlite */; }; + 5A0380142C74D72100D4AADD /* RULanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298729E41BA1006B2C81 /* RULanguageData.sqlite */; }; + 5A0380152C74D72200D4AADD /* RULanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298729E41BA1006B2C81 /* RULanguageData.sqlite */; }; + 5A0380162C74D72600D4AADD /* ESLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298929E41BAD006B2C81 /* ESLanguageData.sqlite */; }; + 5A0380172C74D72700D4AADD /* ESLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298929E41BAD006B2C81 /* ESLanguageData.sqlite */; }; + 5A0380182C74D72700D4AADD /* ESLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298929E41BAD006B2C81 /* ESLanguageData.sqlite */; }; + 5A0380192C74D72800D4AADD /* ESLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298929E41BAD006B2C81 /* ESLanguageData.sqlite */; }; + 5A03801A2C74D72900D4AADD /* ESLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298929E41BAD006B2C81 /* ESLanguageData.sqlite */; }; + 5A03801B2C74D72B00D4AADD /* ESLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298929E41BAD006B2C81 /* ESLanguageData.sqlite */; }; + 5A03801C2C74D72B00D4AADD /* ESLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298929E41BAD006B2C81 /* ESLanguageData.sqlite */; }; + 5A03801D2C74D72C00D4AADD /* ESLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298929E41BAD006B2C81 /* ESLanguageData.sqlite */; }; + 5A03801E2C74D72D00D4AADD /* ESLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298929E41BAD006B2C81 /* ESLanguageData.sqlite */; }; + 5A03801F2C74D72E00D4AADD /* ESLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298929E41BAD006B2C81 /* ESLanguageData.sqlite */; }; + 5A0380202C74D73100D4AADD /* SVLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298B29E41BBE006B2C81 /* SVLanguageData.sqlite */; }; + 5A0380212C74D73100D4AADD /* SVLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298B29E41BBE006B2C81 /* SVLanguageData.sqlite */; }; + 5A0380222C74D73200D4AADD /* SVLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298B29E41BBE006B2C81 /* SVLanguageData.sqlite */; }; + 5A0380232C74D73300D4AADD /* SVLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298B29E41BBE006B2C81 /* SVLanguageData.sqlite */; }; + 5A0380242C74D73400D4AADD /* SVLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298B29E41BBE006B2C81 /* SVLanguageData.sqlite */; }; + 5A0380252C74D73400D4AADD /* SVLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298B29E41BBE006B2C81 /* SVLanguageData.sqlite */; }; + 5A0380262C74D73500D4AADD /* SVLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298B29E41BBE006B2C81 /* SVLanguageData.sqlite */; }; + 5A0380272C74D73600D4AADD /* SVLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298B29E41BBE006B2C81 /* SVLanguageData.sqlite */; }; + 5A0380282C74D73600D4AADD /* SVLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298B29E41BBE006B2C81 /* SVLanguageData.sqlite */; }; + 5A0380292C74D73700D4AADD /* SVLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D15E298B29E41BBE006B2C81 /* SVLanguageData.sqlite */; }; 5A0A4C2E2C207C34003ADE27 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 5A0A4C2B2C207C34003ADE27 /* Localizable.xcstrings */; }; + 5A0A4C352C2AF52D003ADE27 /* RadioTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5A0A4C342C2AF52D003ADE27 /* RadioTableViewCell.xib */; }; + 5A0A4C372C2B0B28003ADE27 /* SelectionViewTemplateViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0A4C362C2B0B28003ADE27 /* SelectionViewTemplateViewController.swift */; }; + 5A0A4C392C2C6AC0003ADE27 /* RadioTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0A4C382C2C6AC0003ADE27 /* RadioTableViewCell.swift */; }; 5A8FFB6B2C5A9D9C00F4B571 /* English.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = D1AFDF3D29CA66D00033BF27 /* English.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 5A8FFB702C5E5A6F00F4B571 /* ENLanguageData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = 5A8FFB6E2C5E575B00F4B571 /* ENLanguageData.sqlite */; }; 69B81EBC2BFB8C77008CAB85 /* TipCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69B81EBB2BFB8C77008CAB85 /* TipCardView.swift */; }; @@ -751,6 +834,18 @@ D1CDEDDA2A85AE9C00098546 /* NBInterfaceVariables.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1CDED802A85A12400098546 /* NBInterfaceVariables.swift */; }; D1CDEDDB2A85AE9D00098546 /* NBInterfaceVariables.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1CDED802A85A12400098546 /* NBInterfaceVariables.swift */; }; D1CDEDDC2A85AE9D00098546 /* NBInterfaceVariables.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1CDED802A85A12400098546 /* NBInterfaceVariables.swift */; }; + D1E385102C977FD200DCE538 /* TranslationData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D1E3850F2C977FD100DCE538 /* TranslationData.sqlite */; }; + D1E385112C977FD200DCE538 /* TranslationData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D1E3850F2C977FD100DCE538 /* TranslationData.sqlite */; }; + D1E385122C977FD200DCE538 /* TranslationData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D1E3850F2C977FD100DCE538 /* TranslationData.sqlite */; }; + D1E385132C977FD200DCE538 /* TranslationData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D1E3850F2C977FD100DCE538 /* TranslationData.sqlite */; }; + D1E385142C977FD200DCE538 /* TranslationData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D1E3850F2C977FD100DCE538 /* TranslationData.sqlite */; }; + D1E385152C977FD200DCE538 /* TranslationData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D1E3850F2C977FD100DCE538 /* TranslationData.sqlite */; }; + D1E385162C977FD200DCE538 /* TranslationData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D1E3850F2C977FD100DCE538 /* TranslationData.sqlite */; }; + D1E385172C977FD200DCE538 /* TranslationData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D1E3850F2C977FD100DCE538 /* TranslationData.sqlite */; }; + D1E385182C977FD200DCE538 /* TranslationData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D1E3850F2C977FD100DCE538 /* TranslationData.sqlite */; }; + D1E385192C977FD200DCE538 /* TranslationData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D1E3850F2C977FD100DCE538 /* TranslationData.sqlite */; }; + D1E3851A2C977FD200DCE538 /* TranslationData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D1E3850F2C977FD100DCE538 /* TranslationData.sqlite */; }; + D1E3851B2C977FD200DCE538 /* TranslationData.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = D1E3850F2C977FD100DCE538 /* TranslationData.sqlite */; }; D1F0367227AAE12200CD7921 /* InterfaceVariables.swift in Sources */ = {isa = PBXBuildFile; fileRef = D190B2492741B31F00705659 /* InterfaceVariables.swift */; }; D1F0367327AAE1B400CD7921 /* CommandVariables.swift in Sources */ = {isa = PBXBuildFile; fileRef = D190B2462741B24F00705659 /* CommandVariables.swift */; }; ED2486F32B0B4E8C0038AE6A /* AboutTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED2486F12B0B4E8C0038AE6A /* AboutTableViewCell.swift */; }; @@ -916,6 +1011,9 @@ 38BD215022D592CA00C6795D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 38DD94F022D6A40000FF8845 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; 5A0A4C2B2C207C34003ADE27 /* Localizable.xcstrings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = ""; }; + 5A0A4C342C2AF52D003ADE27 /* RadioTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = RadioTableViewCell.xib; sourceTree = ""; }; + 5A0A4C362C2B0B28003ADE27 /* SelectionViewTemplateViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectionViewTemplateViewController.swift; sourceTree = ""; }; + 5A0A4C382C2C6AC0003ADE27 /* RadioTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioTableViewCell.swift; sourceTree = ""; }; 5A8FFB6E2C5E575B00F4B571 /* ENLanguageData.sqlite */ = {isa = PBXFileReference; lastKnownFileType = file; path = ENLanguageData.sqlite; sourceTree = ""; }; 69B81EBB2BFB8C77008CAB85 /* TipCardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TipCardView.swift; sourceTree = ""; }; 84AF4D872C3575EA009AE0D2 /* UIDeviceExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIDeviceExtensions.swift; sourceTree = ""; }; @@ -933,7 +1031,7 @@ D111E9B927AFE7B200746F92 /* Annotate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Annotate.swift; sourceTree = ""; }; D1362A37274C040F00C00E48 /* PRIVACY.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = PRIVACY.txt; sourceTree = ""; }; D155AD282BDC6CC20075B18C /* .swiftlint.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = .swiftlint.yml; sourceTree = ""; }; - D15E297E29E41B3B006B2C81 /* FRLanguageData.sqlite */ = {isa = PBXFileReference; lastKnownFileType = file; name = FRLanguageData.sqlite; path = Keyboards/LanguageKeyboards/French/FRLanguageData.sqlite; sourceTree = SOURCE_ROOT; }; + D15E297E29E41B3B006B2C81 /* FRLanguageData.sqlite */ = {isa = PBXFileReference; lastKnownFileType = file; path = FRLanguageData.sqlite; sourceTree = ""; }; D15E298129E41B56006B2C81 /* DELanguageData.sqlite */ = {isa = PBXFileReference; lastKnownFileType = file; path = DELanguageData.sqlite; sourceTree = ""; }; D15E298329E41B74006B2C81 /* ITLanguageData.sqlite */ = {isa = PBXFileReference; lastKnownFileType = file; path = ITLanguageData.sqlite; sourceTree = ""; }; D15E298529E41B8F006B2C81 /* PTLanguageData.sqlite */ = {isa = PBXFileReference; lastKnownFileType = file; path = PTLanguageData.sqlite; sourceTree = ""; }; @@ -1015,6 +1113,7 @@ D1D8B23B2AE4089C0070B817 /* Italian.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Italian.entitlements; sourceTree = ""; }; D1D8B23C2AE408AC0070B817 /* German.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = German.entitlements; sourceTree = ""; }; D1D8B23D2AE408C50070B817 /* French.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = French.entitlements; sourceTree = ""; }; + D1E3850F2C977FD100DCE538 /* TranslationData.sqlite */ = {isa = PBXFileReference; lastKnownFileType = file; path = TranslationData.sqlite; sourceTree = ""; }; D1FF8ED12C6C282500EF50AC /* English.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = English.entitlements; sourceTree = ""; }; ED2486F12B0B4E8C0038AE6A /* AboutTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutTableViewCell.swift; sourceTree = ""; }; ED2486F22B0B4E8C0038AE6A /* AboutTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AboutTableViewCell.xib; sourceTree = ""; }; @@ -1139,6 +1238,7 @@ 1406B7832A2DFCA2001DF45B /* Components */ = { isa = PBXGroup; children = ( + 5A0A4C312C2AF4A7003ADE27 /* SelectionView */, 1406B7852A2DFCBE001DF45B /* InfoChildTableViewCell */, ED2486F02B0B4E610038AE6A /* UITableViewCells */, 140158A12A4EDB2200D14E52 /* TableViewTemplateViewController.swift */, @@ -1281,16 +1381,26 @@ 38BD214D22D592CA00C6795D /* German */ = { isa = PBXGroup; children = ( + D15E298129E41B56006B2C81 /* DELanguageData.sqlite */, D1D8B23C2AE408AC0070B817 /* German.entitlements */, D17193FF27AECCD10038660B /* DECommandVariables.swift */, D17193CF27AEC9EC0038660B /* DEInterfaceVariables.swift */, 38BD214E22D592CA00C6795D /* DEKeyboardViewController.swift */, - D15E298129E41B56006B2C81 /* DELanguageData.sqlite */, 38BD215022D592CA00C6795D /* Info.plist */, ); path = German; sourceTree = ""; }; + 5A0A4C312C2AF4A7003ADE27 /* SelectionView */ = { + isa = PBXGroup; + children = ( + 5A0A4C362C2B0B28003ADE27 /* SelectionViewTemplateViewController.swift */, + 5A0A4C382C2C6AC0003ADE27 /* RadioTableViewCell.swift */, + 5A0A4C342C2AF52D003ADE27 /* RadioTableViewCell.xib */, + ); + path = SelectionView; + sourceTree = ""; + }; 69B81EBA2BFB8C60008CAB85 /* TipCard */ = { isa = PBXGroup; children = ( @@ -1312,12 +1422,12 @@ D109A20C275B6888005E2271 /* French */ = { isa = PBXGroup; children = ( + D15E297E29E41B3B006B2C81 /* FRLanguageData.sqlite */, D1D8B23D2AE408C50070B817 /* French.entitlements */, D17193F727AECC930038660B /* FRCommandVariables.swift */, D17693DC28FC8CC300DF0FBB /* FR-QWERTYInterfaceVariables.swift */, D180EC0228FDFABF0018E29B /* FR-AZERTYInterfaceVariables.swift */, D109A20D275B6888005E2271 /* FRKeyboardViewController.swift */, - D15E297E29E41B3B006B2C81 /* FRLanguageData.sqlite */, D109A20F275B6888005E2271 /* Info.plist */, ); path = French; @@ -1326,11 +1436,11 @@ D109A21B275B68B3005E2271 /* Portuguese */ = { isa = PBXGroup; children = ( + D15E298529E41B8F006B2C81 /* PTLanguageData.sqlite */, D1D8B23A2AE408850070B817 /* Portuguese.entitlements */, D171940727AECCE50038660B /* PTCommandVariables.swift */, D17193D727AECA450038660B /* PTInterfaceVariables.swift */, D109A21C275B68B3005E2271 /* PTKeyboardViewController.swift */, - D15E298529E41B8F006B2C81 /* PTLanguageData.sqlite */, D109A21E275B68B3005E2271 /* Info.plist */, ); path = Portuguese; @@ -1339,11 +1449,11 @@ D1608666270B6D3C00134D48 /* Spanish */ = { isa = PBXGroup; children = ( + D15E298929E41BAD006B2C81 /* ESLanguageData.sqlite */, D1D8B2382AE408620070B817 /* Spanish.entitlements */, D171941727AECD070038660B /* ESCommandVariables.swift */, D17193E727AECAE60038660B /* ESInterfaceVariables.swift */, D1608667270B6D3C00134D48 /* ESKeyboardViewController.swift */, - D15E298929E41BAD006B2C81 /* ESLanguageData.sqlite */, D1608669270B6D3C00134D48 /* Info.plist */, ); path = Spanish; @@ -1352,11 +1462,11 @@ D1671A61275A1E8700A7C118 /* Russian */ = { isa = PBXGroup; children = ( + D15E298729E41BA1006B2C81 /* RULanguageData.sqlite */, D1D8B2392AE408720070B817 /* Russian.entitlements */, D171940F27AECCF50038660B /* RUCommandVariables.swift */, D17193DF27AECAA60038660B /* RUInterfaceVariables.swift */, D1671A70275A1FA200A7C118 /* RUKeyboardViewController.swift */, - D15E298729E41BA1006B2C81 /* RULanguageData.sqlite */, D166FCF1275A197B0047E62B /* Info.plist */, ); path = Russian; @@ -1379,11 +1489,11 @@ D18EA89A2760D4A6001E1358 /* Swedish */ = { isa = PBXGroup; children = ( + D15E298B29E41BBE006B2C81 /* SVLanguageData.sqlite */, D1D8B2372AE4084D0070B817 /* Swedish.entitlements */, D171941F27AECD170038660B /* SVCommandVariables.swift */, D17193EF27AECB350038660B /* SVInterfaceVariables.swift */, D18EA89B2760D4A6001E1358 /* SVKeyboardViewController.swift */, - D15E298B29E41BBE006B2C81 /* SVLanguageData.sqlite */, D18EA89D2760D4A6001E1358 /* Info.plist */, ); path = Swedish; @@ -1456,11 +1566,11 @@ D1AFDE6929CA65740033BF27 /* English */ = { isa = PBXGroup; children = ( + 5A8FFB6E2C5E575B00F4B571 /* ENLanguageData.sqlite */, D1FF8ED12C6C282500EF50AC /* English.entitlements */, D1CDED782A859FB600098546 /* ENCommandVariables.swift */, D1CDED7A2A859FBF00098546 /* ENInterfaceVariables.swift */, D1AFDE6A29CA65740033BF27 /* ENKeyboardViewController.swift */, - 5A8FFB6E2C5E575B00F4B571 /* ENLanguageData.sqlite */, D1AFDE6C29CA65740033BF27 /* Info.plist */, ); path = English; @@ -1491,11 +1601,11 @@ D1B81D2027BBB5320085FE5E /* Italian */ = { isa = PBXGroup; children = ( + D15E298329E41B74006B2C81 /* ITLanguageData.sqlite */, D1D8B23B2AE4089C0070B817 /* Italian.entitlements */, D1B81D4927BBBA200085FE5E /* ITCommandVariables.swift */, D1B81D5227BBBA360085FE5E /* ITInterfaceVariables.swift */, D1B81D2127BBB5320085FE5E /* ITKeyboardViewController.swift */, - D15E298329E41B74006B2C81 /* ITLanguageData.sqlite */, D1B81D2327BBB5320085FE5E /* Info.plist */, ); path = Italian; @@ -1515,6 +1625,7 @@ D1671A61275A1E8700A7C118 /* Russian */, D1608666270B6D3C00134D48 /* Spanish */, D18EA89A2760D4A6001E1358 /* Swedish */, + D1E3850F2C977FD100DCE538 /* TranslationData.sqlite */, ); path = LanguageKeyboards; sourceTree = ""; @@ -1915,10 +2026,12 @@ buildActionMask = 2147483647; files = ( D1895BD22C1D816F009FBEB0 /* Settings.bundle in Resources */, + 5A0A4C352C2AF52D003ADE27 /* RadioTableViewCell.xib in Resources */, 38BD214122D5908100C6795D /* LaunchScreen.storyboard in Resources */, 147797B12A2CD3370044A53E /* InfoChildTableViewCell.xib in Resources */, 5A0A4C2E2C207C34003ADE27 /* Localizable.xcstrings in Resources */, ED2486F42B0B4E8C0038AE6A /* AboutTableViewCell.xib in Resources */, + D1E385102C977FD200DCE538 /* TranslationData.sqlite in Resources */, 38BD213922D5907F00C6795D /* AppScreen.storyboard in Resources */, 38BD213E22D5908100C6795D /* Assets.xcassets in Resources */, ); @@ -1930,8 +2043,16 @@ files = ( D1895BD62C1D816F009FBEB0 /* Settings.bundle in Resources */, CE2C606928FC4DB1005FDAA1 /* Assets.xcassets in Resources */, + 5A03800F2C74D71C00D4AADD /* RULanguageData.sqlite in Resources */, + D1E385142C977FD200DCE538 /* TranslationData.sqlite in Resources */, D15E298229E41B56006B2C81 /* DELanguageData.sqlite in Resources */, D1C0ACDA2719E0AA001E11C3 /* Keyboard.xib in Resources */, + 5A037FE62C74D6D500D4AADD /* ENLanguageData.sqlite in Resources */, + 5A037FFB2C74D70200D4AADD /* ITLanguageData.sqlite in Resources */, + 5A0380232C74D73300D4AADD /* SVLanguageData.sqlite in Resources */, + 5A037FF02C74D6E500D4AADD /* FRLanguageData.sqlite in Resources */, + 5A0380052C74D70D00D4AADD /* PTLanguageData.sqlite in Resources */, + 5A0380192C74D72800D4AADD /* ESLanguageData.sqlite in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1941,8 +2062,16 @@ files = ( D1895BD52C1D816F009FBEB0 /* Settings.bundle in Resources */, D109A22B275B6A8B005E2271 /* Keyboard.xib in Resources */, + 5A03800E2C74D71B00D4AADD /* RULanguageData.sqlite in Resources */, + D1E385132C977FD200DCE538 /* TranslationData.sqlite in Resources */, + 5A037FDC2C74D6CA00D4AADD /* DELanguageData.sqlite in Resources */, CE2C606828FC4DB0005FDAA1 /* Assets.xcassets in Resources */, + 5A037FE52C74D6D500D4AADD /* ENLanguageData.sqlite in Resources */, + 5A037FFA2C74D70100D4AADD /* ITLanguageData.sqlite in Resources */, + 5A0380222C74D73200D4AADD /* SVLanguageData.sqlite in Resources */, D15E297F29E41B3B006B2C81 /* FRLanguageData.sqlite in Resources */, + 5A0380042C74D70D00D4AADD /* PTLanguageData.sqlite in Resources */, + 5A0380182C74D72700D4AADD /* ESLanguageData.sqlite in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1950,10 +2079,18 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 5A037FFE2C74D70400D4AADD /* ITLanguageData.sqlite in Resources */, D1895BDA2C1D816F009FBEB0 /* Settings.bundle in Resources */, + 5A0380132C74D72000D4AADD /* RULanguageData.sqlite in Resources */, + D1E385182C977FD200DCE538 /* TranslationData.sqlite in Resources */, D109A231275B6A8C005E2271 /* Keyboard.xib in Resources */, + 5A037FE02C74D6CD00D4AADD /* DELanguageData.sqlite in Resources */, D15E298629E41B8F006B2C81 /* PTLanguageData.sqlite in Resources */, + 5A037FF42C74D6E800D4AADD /* FRLanguageData.sqlite in Resources */, + 5A0380272C74D73600D4AADD /* SVLanguageData.sqlite in Resources */, + 5A037FEA2C74D6D900D4AADD /* ENLanguageData.sqlite in Resources */, CE2C606B28FC4DB3005FDAA1 /* Assets.xcassets in Resources */, + 5A03801D2C74D72C00D4AADD /* ESLanguageData.sqlite in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1961,9 +2098,17 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 5A0380142C74D72100D4AADD /* RULanguageData.sqlite in Resources */, + 5A0380002C74D70600D4AADD /* ITLanguageData.sqlite in Resources */, D1895BDC2C1D816F009FBEB0 /* Settings.bundle in Resources */, + D1E3851A2C977FD200DCE538 /* TranslationData.sqlite in Resources */, CE2C606D28FC4DB4005FDAA1 /* Assets.xcassets in Resources */, + 5A037FE22C74D6CE00D4AADD /* DELanguageData.sqlite in Resources */, + 5A03800A2C74D71300D4AADD /* PTLanguageData.sqlite in Resources */, D190B2582742525C00705659 /* Keyboard.xib in Resources */, + 5A0380292C74D73700D4AADD /* SVLanguageData.sqlite in Resources */, + 5A037FF62C74D6EA00D4AADD /* FRLanguageData.sqlite in Resources */, + 5A037FEC2C74D6DA00D4AADD /* ENLanguageData.sqlite in Resources */, D15E298A29E41BAD006B2C81 /* ESLanguageData.sqlite in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1972,10 +2117,18 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 5A037FFF2C74D70500D4AADD /* ITLanguageData.sqlite in Resources */, D1895BDB2C1D816F009FBEB0 /* Settings.bundle in Resources */, D15E298829E41BA1006B2C81 /* RULanguageData.sqlite in Resources */, + D1E385192C977FD200DCE538 /* TranslationData.sqlite in Resources */, + 5A037FE12C74D6CD00D4AADD /* DELanguageData.sqlite in Resources */, + 5A0380092C74D71100D4AADD /* PTLanguageData.sqlite in Resources */, D1671A74275A1FC000A7C118 /* Keyboard.xib in Resources */, + 5A037FF52C74D6E900D4AADD /* FRLanguageData.sqlite in Resources */, + 5A0380282C74D73600D4AADD /* SVLanguageData.sqlite in Resources */, + 5A037FEB2C74D6DA00D4AADD /* ENLanguageData.sqlite in Resources */, CE2C606C28FC4DB3005FDAA1 /* Assets.xcassets in Resources */, + 5A03801E2C74D72D00D4AADD /* ESLanguageData.sqlite in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1983,9 +2136,17 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 5A0380152C74D72200D4AADD /* RULanguageData.sqlite in Resources */, + 5A0380012C74D70700D4AADD /* ITLanguageData.sqlite in Resources */, + 5A03801F2C74D72E00D4AADD /* ESLanguageData.sqlite in Resources */, + D1E3851B2C977FD200DCE538 /* TranslationData.sqlite in Resources */, D1895BDD2C1D816F009FBEB0 /* Settings.bundle in Resources */, D15E298C29E41BBE006B2C81 /* SVLanguageData.sqlite in Resources */, + 5A037FE32C74D6CE00D4AADD /* DELanguageData.sqlite in Resources */, + 5A03800B2C74D71400D4AADD /* PTLanguageData.sqlite in Resources */, D18EA8A42760D6EE001E1358 /* Keyboard.xib in Resources */, + 5A037FF72C74D6EA00D4AADD /* FRLanguageData.sqlite in Resources */, + 5A037FED2C74D6DB00D4AADD /* ENLanguageData.sqlite in Resources */, CE2C606E28FC4DB4005FDAA1 /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1994,9 +2155,18 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 5A037FDF2C74D6CC00D4AADD /* DELanguageData.sqlite in Resources */, D1AB5B5629C757A100CCB0C1 /* Keyboard.xib in Resources */, + 5A0380122C74D71F00D4AADD /* RULanguageData.sqlite in Resources */, + D1E385172C977FD200DCE538 /* TranslationData.sqlite in Resources */, D1895BD92C1D816F009FBEB0 /* Settings.bundle in Resources */, D1AB5B5929C757A100CCB0C1 /* Assets.xcassets in Resources */, + 5A037FE92C74D6D800D4AADD /* ENLanguageData.sqlite in Resources */, + 5A037FFD2C74D70400D4AADD /* ITLanguageData.sqlite in Resources */, + 5A0380262C74D73500D4AADD /* SVLanguageData.sqlite in Resources */, + 5A037FF32C74D6E800D4AADD /* FRLanguageData.sqlite in Resources */, + 5A0380082C74D70F00D4AADD /* PTLanguageData.sqlite in Resources */, + 5A03801C2C74D72B00D4AADD /* ESLanguageData.sqlite in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2006,8 +2176,16 @@ files = ( D1AFDF3429CA66D00033BF27 /* Keyboard.xib in Resources */, D1895BD42C1D816F009FBEB0 /* Settings.bundle in Resources */, - 5A8FFB702C5E5A6F00F4B571 /* ENLanguageData.sqlite in Resources */, + 5A03800D2C74D71A00D4AADD /* RULanguageData.sqlite in Resources */, + D1E385122C977FD200DCE538 /* TranslationData.sqlite in Resources */, + 5A037FDB2C74D6C900D4AADD /* DELanguageData.sqlite in Resources */, D1AFDF3729CA66D00033BF27 /* Assets.xcassets in Resources */, + 5A8FFB702C5E5A6F00F4B571 /* ENLanguageData.sqlite in Resources */, + 5A037FF92C74D70000D4AADD /* ITLanguageData.sqlite in Resources */, + 5A0380212C74D73100D4AADD /* SVLanguageData.sqlite in Resources */, + 5A037FEF2C74D6E300D4AADD /* FRLanguageData.sqlite in Resources */, + 5A0380032C74D70C00D4AADD /* PTLanguageData.sqlite in Resources */, + 5A0380172C74D72700D4AADD /* ESLanguageData.sqlite in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2015,9 +2193,18 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 5A037FDA2C74D6C800D4AADD /* DELanguageData.sqlite in Resources */, D1AFDFB129CA66F40033BF27 /* Keyboard.xib in Resources */, + 5A03800C2C74D71900D4AADD /* RULanguageData.sqlite in Resources */, + D1E385112C977FD200DCE538 /* TranslationData.sqlite in Resources */, D1895BD32C1D816F009FBEB0 /* Settings.bundle in Resources */, D1AFDFB429CA66F40033BF27 /* Assets.xcassets in Resources */, + 5A037FE42C74D6D400D4AADD /* ENLanguageData.sqlite in Resources */, + 5A037FF82C74D6FF00D4AADD /* ITLanguageData.sqlite in Resources */, + 5A0380202C74D73100D4AADD /* SVLanguageData.sqlite in Resources */, + 5A037FEE2C74D6E200D4AADD /* FRLanguageData.sqlite in Resources */, + 5A0380022C74D70B00D4AADD /* PTLanguageData.sqlite in Resources */, + 5A0380162C74D72600D4AADD /* ESLanguageData.sqlite in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2025,9 +2212,18 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 5A037FDD2C74D6CA00D4AADD /* DELanguageData.sqlite in Resources */, D1AFE00729CA6E900033BF27 /* Keyboard.xib in Resources */, + 5A0380102C74D71D00D4AADD /* RULanguageData.sqlite in Resources */, + D1E385152C977FD200DCE538 /* TranslationData.sqlite in Resources */, D1895BD72C1D816F009FBEB0 /* Settings.bundle in Resources */, D1AFE00A29CA6E900033BF27 /* Assets.xcassets in Resources */, + 5A037FE72C74D6D600D4AADD /* ENLanguageData.sqlite in Resources */, + 5A037FFC2C74D70300D4AADD /* ITLanguageData.sqlite in Resources */, + 5A0380242C74D73400D4AADD /* SVLanguageData.sqlite in Resources */, + 5A037FF12C74D6E500D4AADD /* FRLanguageData.sqlite in Resources */, + 5A0380062C74D70E00D4AADD /* PTLanguageData.sqlite in Resources */, + 5A03801A2C74D72900D4AADD /* ESLanguageData.sqlite in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2037,8 +2233,16 @@ files = ( D1895BD82C1D816F009FBEB0 /* Settings.bundle in Resources */, D1B81D4127BBB70E0085FE5E /* Keyboard.xib in Resources */, + 5A0380112C74D71F00D4AADD /* RULanguageData.sqlite in Resources */, + D1E385162C977FD200DCE538 /* TranslationData.sqlite in Resources */, + 5A037FDE2C74D6CB00D4AADD /* DELanguageData.sqlite in Resources */, D15E298429E41B74006B2C81 /* ITLanguageData.sqlite in Resources */, + 5A037FF22C74D6E600D4AADD /* FRLanguageData.sqlite in Resources */, + 5A037FE82C74D6D800D4AADD /* ENLanguageData.sqlite in Resources */, + 5A0380252C74D73400D4AADD /* SVLanguageData.sqlite in Resources */, CE2C606A28FC4DB2005FDAA1 /* Assets.xcassets in Resources */, + 5A0380072C74D70F00D4AADD /* PTLanguageData.sqlite in Resources */, + 5A03801B2C74D72B00D4AADD /* ESLanguageData.sqlite in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2126,6 +2330,7 @@ D17193E027AECAA60038660B /* RUInterfaceVariables.swift in Sources */, D1B81D5327BBBA360085FE5E /* ITInterfaceVariables.swift in Sources */, D17193D827AECA450038660B /* PTInterfaceVariables.swift in Sources */, + 5A0A4C392C2C6AC0003ADE27 /* RadioTableViewCell.swift in Sources */, D17193C427AEAD7D0038660B /* AppStyling.swift in Sources */, D111E9AA27AFE78600746F92 /* Plural.swift in Sources */, D1F0367227AAE12200CD7921 /* InterfaceVariables.swift in Sources */, @@ -2139,6 +2344,7 @@ D171944927AEF7290038660B /* KeyboardKeys.swift in Sources */, 147797B32A2CD5AB0044A53E /* ParentTableCellModel.swift in Sources */, 1401589B2A45A07200D14E52 /* WikimediaAndScribe.swift in Sources */, + 5A0A4C372C2B0B28003ADE27 /* SelectionViewTemplateViewController.swift in Sources */, 3045396B293B9DC9003AE55B /* ToolTipViewDatasourceable.swift in Sources */, D1B071A027C6A1AA00FD7DBD /* KeyAltChars.swift in Sources */, D1CDED812A85A12400098546 /* NBInterfaceVariables.swift in Sources */, diff --git a/Scribe/AboutTab/AboutViewController.swift b/Scribe/AboutTab/AboutViewController.swift index 6b462313..46c39045 100644 --- a/Scribe/AboutTab/AboutViewController.swift +++ b/Scribe/AboutTab/AboutViewController.swift @@ -137,10 +137,7 @@ extension AboutViewController { viewController.section = .licenses } - case .appLang: break - case .none: break - case .specificLang: break - case .externalLink: break + default: break } if let selectedIndexPath = tableView.indexPathForSelectedRow { diff --git a/Scribe/Assets.xcassets/MenuIcons/radioButton.imageset/Contents.json b/Scribe/Assets.xcassets/MenuIcons/radioButton.imageset/Contents.json new file mode 100644 index 00000000..843f3361 --- /dev/null +++ b/Scribe/Assets.xcassets/MenuIcons/radioButton.imageset/Contents.json @@ -0,0 +1,52 @@ +{ + "images" : [ + { + "filename" : "Image.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "radioButton.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Scribe/Assets.xcassets/MenuIcons/radioButton.imageset/Image.png b/Scribe/Assets.xcassets/MenuIcons/radioButton.imageset/Image.png new file mode 100644 index 00000000..fa790adb Binary files /dev/null and b/Scribe/Assets.xcassets/MenuIcons/radioButton.imageset/Image.png differ diff --git a/Scribe/Assets.xcassets/MenuIcons/radioButton.imageset/radioButton.png b/Scribe/Assets.xcassets/MenuIcons/radioButton.imageset/radioButton.png new file mode 100644 index 00000000..c01c9e8e Binary files /dev/null and b/Scribe/Assets.xcassets/MenuIcons/radioButton.imageset/radioButton.png differ diff --git a/Scribe/Assets.xcassets/MenuIcons/radioButtonSelected.imageset/Contents.json b/Scribe/Assets.xcassets/MenuIcons/radioButtonSelected.imageset/Contents.json new file mode 100644 index 00000000..840012a1 --- /dev/null +++ b/Scribe/Assets.xcassets/MenuIcons/radioButtonSelected.imageset/Contents.json @@ -0,0 +1,52 @@ +{ + "images" : [ + { + "filename" : "radioButtonSelected.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "radioButtonSelected 1.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Scribe/Assets.xcassets/MenuIcons/radioButtonSelected.imageset/radioButtonSelected 1.png b/Scribe/Assets.xcassets/MenuIcons/radioButtonSelected.imageset/radioButtonSelected 1.png new file mode 100644 index 00000000..813f5ac6 Binary files /dev/null and b/Scribe/Assets.xcassets/MenuIcons/radioButtonSelected.imageset/radioButtonSelected 1.png differ diff --git a/Scribe/Assets.xcassets/MenuIcons/radioButtonSelected.imageset/radioButtonSelected.png b/Scribe/Assets.xcassets/MenuIcons/radioButtonSelected.imageset/radioButtonSelected.png new file mode 100644 index 00000000..813f5ac6 Binary files /dev/null and b/Scribe/Assets.xcassets/MenuIcons/radioButtonSelected.imageset/radioButtonSelected.png differ diff --git a/Scribe/Base.lproj/AppScreen.storyboard b/Scribe/Base.lproj/AppScreen.storyboard index cd9eecb3..8a442724 100644 --- a/Scribe/Base.lproj/AppScreen.storyboard +++ b/Scribe/Base.lproj/AppScreen.storyboard @@ -576,11 +576,33 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/Scribe/Components/InfoChildTableViewCell/InfoChildTableViewCell.swift b/Scribe/Components/InfoChildTableViewCell/InfoChildTableViewCell.swift index c2c85e00..ffca1f99 100644 --- a/Scribe/Components/InfoChildTableViewCell/InfoChildTableViewCell.swift +++ b/Scribe/Components/InfoChildTableViewCell/InfoChildTableViewCell.swift @@ -31,6 +31,14 @@ final class InfoChildTableViewCell: UITableViewCell { @IBOutlet var titleLabelPad: UILabel! var titleLabel: UILabel! + @IBOutlet var subLabelPhone: UILabel! + @IBOutlet var subLabelPad: UILabel! + var subLabel: UILabel! + + @IBOutlet var iconImageViewPhone: UIImageView! + @IBOutlet var iconImageViewPad: UIImageView! + var iconImageView: UIImageView! + @IBOutlet var toggleSwitchPhone: UISwitch! @IBOutlet var toggleSwitchPad: UISwitch! var toggleSwitch: UISwitch! @@ -45,18 +53,26 @@ final class InfoChildTableViewCell: UITableViewCell { func setTableView() { if DeviceType.isPad { titleLabel = titleLabelPad + subLabel = subLabelPad + iconImageView = iconImageViewPad toggleSwitch = toggleSwitchPad descriptionLabel = descriptionLabelPad titleLabelPhone.removeFromSuperview() + subLabelPhone.removeFromSuperview() + iconImageViewPhone.removeFromSuperview() toggleSwitchPhone.removeFromSuperview() descriptionLabelPhone.removeFromSuperview() } else { titleLabel = titleLabelPhone + subLabel = subLabelPhone + iconImageView = iconImageViewPhone toggleSwitch = toggleSwitchPhone descriptionLabel = descriptionLabelPhone titleLabelPad.removeFromSuperview() + subLabelPad.removeFromSuperview() + iconImageViewPad.removeFromSuperview() toggleSwitchPad.removeFromSuperview() descriptionLabelPad.removeFromSuperview() } @@ -96,26 +112,33 @@ final class InfoChildTableViewCell: UITableViewCell { descriptionLabel.removeFromSuperview() } - if !section.hasToggle { - let disclosureIcon = UIImage(systemName: "chevron.right") - let accessory = UIImageView( - frame: CGRect( - x: 0, y: 0, width: (disclosureIcon?.size.width)!, height: (disclosureIcon?.size.height)! - ) - ) - accessory.image = disclosureIcon - accessory.tintColor = menuOptionColor - accessoryView = accessory - toggleSwitch.isHidden = true - } else { + if section.hasToggle { accessoryType = .none toggleSwitch.isHidden = false - } - fetchSwitchStateForCell() + fetchSwitchStateForCell() - toggleSwitch.onTintColor = .init(ScribeColor.scribeCTA).withAlphaComponent(0.4) - toggleSwitch.thumbTintColor = toggleSwitch.isOn ? .init(.scribeCTA) : .lightGray + toggleSwitch.onTintColor = .init(ScribeColor.scribeCTA).withAlphaComponent(0.4) + toggleSwitch.thumbTintColor = toggleSwitch.isOn ? .init(.scribeCTA) : .lightGray + } else { + iconImageView.image = UIImage(systemName: "chevron.right") + iconImageView.tintColor = menuOptionColor + toggleSwitch.isHidden = true + } + + if section.sectionState == .translateLang { + var langTranslateLanguage = "English" + if let selectedLang = userDefaults.string(forKey: languageCode + "TranslateLanguage") { + langTranslateLanguage = getKeyInDict(givenValue: selectedLang, dict: languagesAbbrDict) + } else { + userDefaults.set("en", forKey: languageCode + "TranslateLanguage") + } + let currentLang = "_global." + langTranslateLanguage.lowercased() + subLabel.text = NSLocalizedString(currentLang, value: langTranslateLanguage, comment: "") + subLabel.textColor = menuOptionColor + } else { + subLabel.removeFromSuperview() + } } @IBAction func switchDidChange(_: UISwitch) { diff --git a/Scribe/Components/InfoChildTableViewCell/InfoChildTableViewCell.xib b/Scribe/Components/InfoChildTableViewCell/InfoChildTableViewCell.xib index 51c84a4c..86400be2 100644 --- a/Scribe/Components/InfoChildTableViewCell/InfoChildTableViewCell.xib +++ b/Scribe/Components/InfoChildTableViewCell/InfoChildTableViewCell.xib @@ -3,7 +3,7 @@ - + @@ -20,16 +20,23 @@ + + + + + + + - + @@ -38,7 +45,7 @@ + + + + + + + + - + @@ -65,7 +88,7 @@ + + + + + + + + + + + + + diff --git a/Scribe/Components/SelectionView/RadioTableViewCell.swift b/Scribe/Components/SelectionView/RadioTableViewCell.swift new file mode 100644 index 00000000..89414e8b --- /dev/null +++ b/Scribe/Components/SelectionView/RadioTableViewCell.swift @@ -0,0 +1,82 @@ +/** + * DESCRIPTION_OF_THE_PURPOSE_OF_THE_FILE + * + * Copyright (C) 2023 Scribe + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import UIKit + +final class RadioTableViewCell: UITableViewCell { + + // MARK: - Constants + + static let reuseIdentifier = String(describing: InfoChildTableViewCell.self) + + // MARK: - Properties + + @IBOutlet var titleLabelPhone: UILabel! + @IBOutlet var titleLabelPad: UILabel! + var titleLabel: UILabel! + + @IBOutlet var iconImageViewPhone: UIImageView! + @IBOutlet var iconImageViewPad: UIImageView! + var iconImageView: UIImageView! + + var section: Section? + var parentSection: Section? + var inUse: Bool = false + + func setTableView() { + if DeviceType.isPad { + titleLabel = titleLabelPad + iconImageView = iconImageViewPad + + titleLabelPhone.removeFromSuperview() + iconImageViewPhone.removeFromSuperview() + } else { + titleLabel = titleLabelPhone + iconImageView = iconImageViewPhone + + titleLabelPad.removeFromSuperview() + iconImageViewPad.removeFromSuperview() + } + } + + var selectedLang: String { + guard let section = section, + case let .specificLang(lang) = section.sectionState else { return "n/a" } + + return lang + } + + var togglePurpose: UserInteractiveState { + guard let section = section, + case let .none(action) = section.sectionState else { return .none } + + return action + } + + // MARK: - Functions + + func configureCell(for section: Section) { + self.section = section + selectionStyle = .none + + setTableView() + titleLabel.text = section.sectionTitle + iconImageView.image = UIImage(named: "radioButton") + } +} diff --git a/Scribe/Components/SelectionView/RadioTableViewCell.xib b/Scribe/Components/SelectionView/RadioTableViewCell.xib new file mode 100644 index 00000000..b1a53d2c --- /dev/null +++ b/Scribe/Components/SelectionView/RadioTableViewCell.xib @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Scribe/Components/SelectionView/SelectionViewTemplateViewController.swift b/Scribe/Components/SelectionView/SelectionViewTemplateViewController.swift new file mode 100644 index 00000000..b7e1c88c --- /dev/null +++ b/Scribe/Components/SelectionView/SelectionViewTemplateViewController.swift @@ -0,0 +1,95 @@ +/** + * This file describes + * + * Copyright (C) 2024 Scribe + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import UIKit + +final class SelectionViewTemplateViewController: BaseTableViewController { + // MARK: - Properties + + override var dataSet: [ParentTableCellModel] { + tableData + } + + private var tableData: [ParentTableCellModel] = [] + private var parentSection: Section? + private var selectedPath: IndexPath? + + let userDefaults = UserDefaults(suiteName: "group.be.scri.userDefaultsContainer")! + + private var langCode: String = "de" + + // MARK: - Functions + + override func viewDidLoad() { + super.viewDidLoad() + tableView.register( + UINib(nibName: "RadioTableViewCell", bundle: nil), + forCellReuseIdentifier: RadioTableViewCell.reuseIdentifier + ) + } + + func configureTable(for tableData: [ParentTableCellModel], parentSection: Section, langCode: String) { + self.tableData = tableData + self.parentSection = parentSection + self.langCode = langCode + + title = parentSection.sectionTitle + } +} + +// MARK: - UITableViewDataSource + +extension SelectionViewTemplateViewController { + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + guard let cell = tableView.dequeueReusableCell( + withIdentifier: RadioTableViewCell.reuseIdentifier, + for: indexPath + ) as? RadioTableViewCell else { + fatalError("Failed to dequeue RadioTableViewCell.") + } + cell.parentSection = parentSection + cell.configureCell(for: tableData[indexPath.section].section[indexPath.row]) + cell.backgroundColor = lightWhiteDarkBlackColor + if cell.selectedLang == userDefaults.string(forKey: langCode + "TranslateLanguage") { + selectedPath = indexPath + cell.iconImageView.image = UIImage(named: "radioButtonSelected") + } + + return cell + } + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if selectedPath != nil { + let previousCell = tableView.cellForRow(at: selectedPath!) as! RadioTableViewCell + previousCell.iconImageView.image = UIImage(named: "radioButton") + } + + let cell = tableView.cellForRow(at: indexPath) as! RadioTableViewCell + cell.iconImageView.image = UIImage(named: "radioButtonSelected") + selectedPath = indexPath + + let dictionaryKey = langCode + "TranslateLanguage" + userDefaults.setValue(cell.selectedLang, forKey: dictionaryKey) + + if let selectedIndexPath = tableView.indexPathForSelectedRow { + tableView.deselectRow(at: selectedIndexPath, animated: true) + } + navigationController?.popViewController(animated: true) + } +} diff --git a/Scribe/Components/TableViewTemplateViewController.swift b/Scribe/Components/TableViewTemplateViewController.swift index cc815581..0d210749 100644 --- a/Scribe/Components/TableViewTemplateViewController.swift +++ b/Scribe/Components/TableViewTemplateViewController.swift @@ -29,6 +29,8 @@ final class TableViewTemplateViewController: BaseTableViewController { private var tableData: [ParentTableCellModel] = [] private var parentSection: Section? + let userDefaults = UserDefaults(suiteName: "group.be.scri.userDefaultsContainer")! + private var langCode: String { guard let parentSection else { return "" @@ -57,6 +59,15 @@ final class TableViewTemplateViewController: BaseTableViewController { title = parentSection.sectionTitle } + + // Refreshes to check for changes when a translation language is selected + override func viewWillAppear(_ animated: Bool) { + for cell in tableView.visibleCells as! [InfoChildTableViewCell] where cell.section?.sectionState == .translateLang { + let langTranslateLanguage = getKeyInDict(givenValue: (userDefaults.string(forKey: langCode + "TranslateLanguage") ?? "en"), dict: languagesAbbrDict) + let currentLang = "_global." + langTranslateLanguage.lowercased() + cell.subLabel.text = NSLocalizedString(currentLang, value: langTranslateLanguage, comment: "") + } + } } // MARK: UITableViewDataSource @@ -75,4 +86,27 @@ extension TableViewTemplateViewController { return cell } + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + let tableSection = tableData[indexPath.section] + let section = tableSection.section[indexPath.row] + + if section.sectionState == .translateLang { + if let viewController = storyboard?.instantiateViewController( + identifier: "SelectionViewTemplateViewController" + ) as? SelectionViewTemplateViewController { + var data = SettingsTableData.translateLangSettingsData + + // Removes keyboard language from possible translation languages + let langCodeIndex = SettingsTableData.translateLangSettingsData[0].section.firstIndex(where: { s in + s.sectionState == .specificLang(langCode) + }) ?? -1 + data[0].section.remove(at: langCodeIndex) + + viewController.configureTable(for: data, parentSection: section, langCode: langCode) + + navigationController?.pushViewController(viewController, animated: true) + } + } + } } diff --git a/Scribe/Extensions/UIDeviceExtensions.swift b/Scribe/Extensions/UIDeviceExtensions.swift index ff14a169..593d7dfc 100644 --- a/Scribe/Extensions/UIDeviceExtensions.swift +++ b/Scribe/Extensions/UIDeviceExtensions.swift @@ -21,12 +21,8 @@ import UIKit extension UIDevice { public static var hasNotch: Bool { - if #available(iOS 11.0, *) { - if UIApplication.shared.windows.count == 0 { return false } - let top = UIApplication.shared.windows[0].safeAreaInsets.top - return top > 24 - } else { - return false - } + if UIApplication.shared.windows.count == 0 { return false } + let top = UIApplication.shared.windows[0].safeAreaInsets.top + return top > 24 } } diff --git a/Scribe/ParentTableCellModel.swift b/Scribe/ParentTableCellModel.swift index 1e5df07f..68ea095e 100644 --- a/Scribe/ParentTableCellModel.swift +++ b/Scribe/ParentTableCellModel.swift @@ -57,6 +57,7 @@ struct Section { enum SectionState: Equatable { case github case matrix + case mastodon case wikimedia case shareScribe case rateScribe @@ -69,9 +70,9 @@ enum SectionState: Equatable { case licenses case appLang case specificLang(String) - case none(UserInteractiveState) + case translateLang case externalLink - case mastodon + case none(UserInteractiveState) } enum UserInteractiveState { diff --git a/Scribe/SettingsTab/SettingsTableData.swift b/Scribe/SettingsTab/SettingsTableData.swift index 14b8fad9..d65d9329 100644 --- a/Scribe/SettingsTab/SettingsTableData.swift +++ b/Scribe/SettingsTab/SettingsTableData.swift @@ -42,6 +42,16 @@ enum SettingsTableData { ] static let languageSettingsData: [ParentTableCellModel] = [ + ParentTableCellModel( + headingTitle: NSLocalizedString("app.settings.translation", value: "Translation", comment: ""), + section: [ + Section( + sectionTitle: NSLocalizedString("app.settings.translation.translateLang", value: "Translation language", comment: ""), + sectionState: .translateLang + ) + ], + hasDynamicData: nil + ), ParentTableCellModel( headingTitle: NSLocalizedString("app.settings.layout", value: "Layout", comment: ""), section: [ @@ -81,6 +91,14 @@ enum SettingsTableData { ) ] + static let translateLangSettingsData: [ParentTableCellModel] = [ + ParentTableCellModel( + headingTitle: NSLocalizedString("app.settings.translation.translateLang.caption", value: "Choose a language to translate from", comment: ""), + section: getTranslateLanguages(), + hasDynamicData: nil + ) + ] + static func getInstalledKeyboardsSections() -> [Section] { var installedKeyboards = [String]() @@ -90,8 +108,8 @@ enum SettingsTableData { let customKeyboardExtension = appBundleIdentifier + "." for keyboard in keyboards where keyboard.hasPrefix(customKeyboardExtension) { - let lang = keyboard.replacingOccurrences(of: customKeyboardExtension, with: "") - installedKeyboards.append(lang.capitalized) + let lang = keyboard.replacingOccurrences(of: customKeyboardExtension, with: "") + installedKeyboards.append(lang.capitalized) } var sections = [Section]() @@ -110,4 +128,22 @@ enum SettingsTableData { return sections } + + static func getTranslateLanguages() -> [Section] { + var sections = [Section]() + + for lang in languagesAbbrDict.keys.sorted() { + guard let abbreviation = languagesAbbrDict[lang] else { + fatalError("Abbreviation not found for language: \(lang)") + } + let newSection = Section( + sectionTitle: languagesStringDict[lang]!, + sectionState: .specificLang(abbreviation) + ) + + sections.append(newSection) + } + + return sections + } } diff --git a/Scribe/SettingsTab/SettingsViewController.swift b/Scribe/SettingsTab/SettingsViewController.swift index cea58850..26533422 100644 --- a/Scribe/SettingsTab/SettingsViewController.swift +++ b/Scribe/SettingsTab/SettingsViewController.swift @@ -178,14 +178,14 @@ extension SettingsViewController: UITableViewDelegate { var data = SettingsTableData.languageSettingsData // Check if the device is an iPad to remove the Layout Section. if DeviceType.isPad { - for menuOption in data[0].section { + for menuOption in data[1].section { if menuOption.sectionState == .none(.toggleAccentCharacters) || menuOption.sectionState == .none(.toggleCommaAndPeriod) { - data[0].section.remove(at: 0) + data[1].section.remove(at: 0) } } - if data[0].section.isEmpty { - data.remove(at: 0) + if data[1].section.isEmpty { + data.remove(at: 1) } } else { // Languages where we can disable accent keys. @@ -195,15 +195,15 @@ extension SettingsViewController: UITableViewDelegate { languagesStringDict["Swedish"]! ] - let accentKeyOptionIndex = SettingsTableData.languageSettingsData[0].section.firstIndex(where: { s in + let accentKeyOptionIndex = SettingsTableData.languageSettingsData[1].section.firstIndex(where: { s in s.sectionTitle.elementsEqual(NSLocalizedString("app.settings.layout.disableAccentCharacters", value: "Disable accent characters", comment: "")) }) ?? -1 // If there are no accent keys we can remove the `Disable accent characters` option. if accentKeyLanguages.firstIndex(of: section.sectionTitle) == nil && accentKeyOptionIndex != -1 { - data[0].section.remove(at: accentKeyOptionIndex) + data[1].section.remove(at: accentKeyOptionIndex) } else if accentKeyLanguages.firstIndex(of: section.sectionTitle) != nil && accentKeyOptionIndex == -1 { - data[0].section.insert(Section( + data[1].section.insert(Section( sectionTitle: NSLocalizedString("app.settings.layout.disableAccentCharacters", value: "Disable accent characters", comment: ""), imageString: "info.circle", hasToggle: true, diff --git a/Scribe/TipCard/TipCardView.swift b/Scribe/TipCard/TipCardView.swift index ae83ab3d..009f8550 100644 --- a/Scribe/TipCard/TipCardView.swift +++ b/Scribe/TipCard/TipCardView.swift @@ -27,7 +27,6 @@ struct TipCardView: View { var infoText: String @Binding var tipCardState: Bool var onDismiss: (() -> Void)? - let ok = "OK" var body: some View { ZStack { diff --git a/Scribe/i18n/Scribe-i18n/Localizable.xcstrings b/Scribe/i18n/Scribe-i18n/Localizable.xcstrings index a40f89b6..ebe87a7e 100644 --- a/Scribe/i18n/Scribe-i18n/Localizable.xcstrings +++ b/Scribe/i18n/Scribe-i18n/Localizable.xcstrings @@ -1739,7 +1739,6 @@ }, "app.settings.translation" : { "comment" : "", - "extractionState" : "stale", "localizations" : { "de" : { "stringUnit" : { @@ -1769,7 +1768,6 @@ }, "app.settings.translation.translateLang" : { "comment" : "", - "extractionState" : "stale", "localizations" : { "de" : { "stringUnit" : { @@ -1799,7 +1797,6 @@ }, "app.settings.translation.translateLang.caption" : { "comment" : "", - "extractionState" : "stale", "localizations" : { "de" : { "stringUnit" : {