From 2fdd3fd6ecb12be67b5d3c5a439ce9a9a877fc24 Mon Sep 17 00:00:00 2001 From: Danny Moesch Date: Sun, 20 Jan 2019 11:24:57 +0100 Subject: [PATCH] Localize also multiline strings --- pass.xcodeproj/project.pbxproj | 16 ++ pass/Base.lproj/Main.storyboard | 143 +++--------------- .../UICodeHighlightingLabel.swift | 48 ++++++ pass/UserInterface/UILocalizedLabel.swift | 18 +++ pass/en.lproj/Localizable.strings | 27 ++++ 5 files changed, 130 insertions(+), 122 deletions(-) create mode 100644 pass/UserInterface/UICodeHighlightingLabel.swift create mode 100644 pass/UserInterface/UILocalizedLabel.swift diff --git a/pass.xcodeproj/project.pbxproj b/pass.xcodeproj/project.pbxproj index 1818e56..cb7a4ed 100644 --- a/pass.xcodeproj/project.pbxproj +++ b/pass.xcodeproj/project.pbxproj @@ -29,6 +29,8 @@ 30BF5ED721ED2434000E4154 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 30BF5ED521ED2434000E4154 /* Localizable.stringsdict */; }; 30C25DBD21F3599E00BB27BB /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 30C25DBF21F3599E00BB27BB /* InfoPlist.strings */; }; 30C25DC021F35A6900BB27BB /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 30C25DC221F35A6900BB27BB /* InfoPlist.strings */; }; + 30C25DD721F4834D00BB27BB /* UILocalizedLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30C25DD521F4834D00BB27BB /* UILocalizedLabel.swift */; }; + 30C25DD821F4834D00BB27BB /* UICodeHighlightingLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30C25DD621F4834D00BB27BB /* UICodeHighlightingLabel.swift */; }; 30FD2F78214D9E0E005E0A92 /* ParserTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30FD2F77214D9E0E005E0A92 /* ParserTest.swift */; }; 61326CDA7A73757FB68DCB04 /* Pods_passKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAB3F5541E51ADC8C6B56642 /* Pods_passKit.framework */; }; A20691F41F2A3D0E0096483D /* SecurePasteboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = A20691F31F2A3D0E0096483D /* SecurePasteboard.swift */; }; @@ -215,6 +217,8 @@ 30C25DA921F34D2800BB27BB /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Main.strings; sourceTree = ""; }; 30C25DBE21F3599E00BB27BB /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 30C25DC121F35A6900BB27BB /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + 30C25DD521F4834D00BB27BB /* UILocalizedLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UILocalizedLabel.swift; sourceTree = ""; }; + 30C25DD621F4834D00BB27BB /* UICodeHighlightingLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UICodeHighlightingLabel.swift; sourceTree = ""; }; 30FD2F77214D9E0E005E0A92 /* ParserTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParserTest.swift; sourceTree = ""; }; 31C3033E8868D05B2C55C8B1 /* Pods-passExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-passExtension.debug.xcconfig"; path = "Pods/Target Support Files/Pods-passExtension/Pods-passExtension.debug.xcconfig"; sourceTree = ""; }; 3A5620D17DF5E86B61761D0E /* Pods_pass.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_pass.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -450,6 +454,15 @@ path = Models; sourceTree = ""; }; + 30C25DD421F4831200BB27BB /* UserInterface */ = { + isa = PBXGroup; + children = ( + 30C25DD621F4834D00BB27BB /* UICodeHighlightingLabel.swift */, + 30C25DD521F4834D00BB27BB /* UILocalizedLabel.swift */, + ); + path = UserInterface; + sourceTree = ""; + }; A2168A801EFD431A005EA873 /* Controllers */ = { isa = PBXGroup; children = ( @@ -705,6 +718,7 @@ DC917BD61E2E8231000FDF54 /* AppDelegate.swift */, DC19400D1E4B3A340077E0A3 /* Models */, DC19400C1E4B39400077E0A3 /* Controllers */, + 30C25DD421F4831200BB27BB /* UserInterface */, DC19400F1E4B3A9E0077E0A3 /* Views */, DC19400E1E4B3A610077E0A3 /* Helpers */, DC917BDD1E2E8231000FDF54 /* Assets.xcassets */, @@ -1271,7 +1285,9 @@ DCDDEAB31E4896BF00F68193 /* PasswordDetailTitleTableViewCell.swift in Sources */, A2A7813F1E97DBD9001311F5 /* QRScannerController.swift in Sources */, DC4914991E434600007FF592 /* PasswordDetailTableViewController.swift in Sources */, + 30C25DD821F4834D00BB27BB /* UICodeHighlightingLabel.swift in Sources */, DC962CDF1E4B62C10033B5D8 /* AboutTableViewController.swift in Sources */, + 30C25DD721F4834D00BB27BB /* UILocalizedLabel.swift in Sources */, DC5734AE1E439AD400D09270 /* PasswordsViewController.swift in Sources */, DCD3C65E1EFB9BB400CBE842 /* SettingsSplitViewController.swift in Sources */, A20691F41F2A3D0E0096483D /* SecurePasteboard.swift in Sources */, diff --git a/pass/Base.lproj/Main.storyboard b/pass/Base.lproj/Main.storyboard index 853cdc6..c55866e 100644 --- a/pass/Base.lproj/Main.storyboard +++ b/pass/Base.lproj/Main.storyboard @@ -527,36 +527,17 @@ - @@ -981,34 +962,17 @@ Phone Support PIN #: 84719 - @@ -1351,55 +1315,17 @@ Phone Support PIN #: 84719 - @@ -1565,44 +1491,17 @@ The clipboard will be cleared 45s after pasting. - @@ -1870,7 +1769,7 @@ The clipboard will be cleared 45s after pasting. - + diff --git a/pass/UserInterface/UICodeHighlightingLabel.swift b/pass/UserInterface/UICodeHighlightingLabel.swift new file mode 100644 index 0000000..4fbad4c --- /dev/null +++ b/pass/UserInterface/UICodeHighlightingLabel.swift @@ -0,0 +1,48 @@ +/* + UICodeHighlightingLabel.swift + pass + + Created by Danny Moesch on 20.01.19. + Copyright © 2019 Bob Sun. All rights reserved. + */ + +import UIKit +import passKit + +class UICodeHighlightingLabel: UILocalizedLabel { + + private static let CODE_ATTRIBUTES: [NSAttributedString.Key: Any] = [.font: UIFont(name: "Menlo-Regular", size: 12)!] + private static let ATTRIBUTED_NEWLINE = NSAttributedString(string: "\n") + + override func awakeFromNib() { + super.awakeFromNib() + guard let text = text else { + return + } + attributedText = formatCode(in: text) + } + + /// Format code sections in a multiline string block. + /// + /// A line in the string is interpreted as a code section if it starts with two spaces. + /// + /// - Parameter text: Multiline string block + /// - Returns: Same multiline string block with code sections formatted + private func formatCode(in text: String) -> NSMutableAttributedString { + let formattedText = text + .split(omittingEmptySubsequences: false) { + $0 == "\n" || $0 == "\r\n" + }.map { line -> NSAttributedString in + if line.starts(with: " ") { + return NSAttributedString(string: String(line), attributes: UICodeHighlightingLabel.CODE_ATTRIBUTES) + } + return NSAttributedString(string: String(line)) + }.reduce(into: NSMutableAttributedString(string: "")) { + $0.append($1) + $0.append(UICodeHighlightingLabel.ATTRIBUTED_NEWLINE) + } + formattedText.deleteCharacters(in: NSRange(location: formattedText.length - 1, length: 1)) + return formattedText + } +} + diff --git a/pass/UserInterface/UILocalizedLabel.swift b/pass/UserInterface/UILocalizedLabel.swift new file mode 100644 index 0000000..6c2b0d1 --- /dev/null +++ b/pass/UserInterface/UILocalizedLabel.swift @@ -0,0 +1,18 @@ +/* + UILocalizedLabel.swift + pass + + Created by Danny Moesch on 20.01.19. + Copyright © 2019 Bob Sun. All rights reserved. + */ + +import UIKit +import passKit + +class UILocalizedLabel: UILabel { + + override func awakeFromNib() { + super.awakeFromNib() + text = text?.localize() + } +} diff --git a/pass/en.lproj/Localizable.strings b/pass/en.lproj/Localizable.strings index b958a37..043fbd7 100644 --- a/pass/en.lproj/Localizable.strings +++ b/pass/en.lproj/Localizable.strings @@ -243,3 +243,30 @@ "WannaUseIt?" = "Wanna use it?"; "SeemsLikeYouHaveCopiedSomething." = "It seems like you have copied something."; "FirstStringIs:" = "The first string is:"; + +// Multiline strings +"SshAsciiArmorCopyExplanation." = "The ASCII-armored key format is similar to unencoded documents rather than the binary format. Use + +$ cat ~/.ssh/id_rsa + +to get the key in this specific format. The clipboard will be cleared 45s after pasting."; + +"SshAsciiArmorServerExplanation." = "The ASCII-armored key format is similar to unencoded documents rather than the binary format. Use + +$ cat ~/.ssh/id_rsa + +to get the key in this specific format. Subsequently, copy it to your secured key server."; + +"GpgAsciiArmorCopyExplanation." = "GnuPG supports the command-line option \"-a\" that causes output to be generated in an ASCII-armored format similar to unencoded documents rather than the binary format. Use + +$ gpg --export -a KEY_ID +$ gpg --export-secret-keys -a KEY_ID + +to get the public and the private key in this specific format. The clipboard will be cleared 45s after pasting."; + +"GpgAsciiArmorServerExplanation." = "GnuPG supports the command-line option \"-a\" that causes output to be generated in an ASCII-armored format similar to unencoded documents rather than the binary format. Use + +$ gpg --export -a KEY_ID +$ gpg --export-secret-keys -a KEY_ID + +to get the public and the private key in this specific format. Subsequently, copy them to your secured key server.";