diff --git a/Jottre.xcodeproj/project.pbxproj b/Jottre.xcodeproj/project.pbxproj index f90c450..8b46216 100644 --- a/Jottre.xcodeproj/project.pbxproj +++ b/Jottre.xcodeproj/project.pbxproj @@ -7,6 +7,15 @@ objects = { /* Begin PBXBuildFile section */ + A6BB130725B45ECB008C5D8A /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6BB130625B45ECB008C5D8A /* SettingsViewController.swift */; }; + A6BB130C25B46057008C5D8A /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6BB130B25B46057008C5D8A /* Settings.swift */; }; + A6BB131025B46BA2008C5D8A /* SettingsNavigationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6BB130F25B46BA2008C5D8A /* SettingsNavigationViewController.swift */; }; + A6BB131325B46E2D008C5D8A /* SettingsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6BB131225B46E2D008C5D8A /* SettingsCell.swift */; }; + A6BB131B25B472F9008C5D8A /* AppearanceSettingsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6BB131A25B472F9008C5D8A /* AppearanceSettingsCell.swift */; }; + A6BB134125B49FDF008C5D8A /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = A6BB134325B49FDF008C5D8A /* Localizable.strings */; }; + A6BB134825B4A469008C5D8A /* SettingsButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6BB134725B4A469008C5D8A /* SettingsButton.swift */; }; + A6BB134C25B4AEFC008C5D8A /* SettingsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6BB134B25B4AEFC008C5D8A /* SettingsExtensions.swift */; }; + A6BB134F25B4B2D0008C5D8A /* CloudSettingsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6BB134E25B4B2D0008C5D8A /* CloudSettingsCell.swift */; }; A6E3B7EC25B3260200C65157 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6E3B7EB25B3260200C65157 /* AppDelegate.swift */; }; A6E3B7EE25B3260200C65157 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6E3B7ED25B3260200C65157 /* SceneDelegate.swift */; }; A6E3B7F525B3260300C65157 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A6E3B7F425B3260300C65157 /* Assets.xcassets */; }; @@ -30,6 +39,17 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + A6BB130625B45ECB008C5D8A /* SettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = ""; }; + A6BB130B25B46057008C5D8A /* Settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = ""; }; + A6BB130F25B46BA2008C5D8A /* SettingsNavigationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsNavigationViewController.swift; sourceTree = ""; }; + A6BB131225B46E2D008C5D8A /* SettingsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsCell.swift; sourceTree = ""; }; + A6BB131A25B472F9008C5D8A /* AppearanceSettingsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppearanceSettingsCell.swift; sourceTree = ""; }; + A6BB134025B49F81008C5D8A /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/LaunchScreen.strings; sourceTree = ""; }; + A6BB134225B49FDF008C5D8A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + A6BB134525B49FE0008C5D8A /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; + A6BB134725B4A469008C5D8A /* SettingsButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsButton.swift; sourceTree = ""; }; + A6BB134B25B4AEFC008C5D8A /* SettingsExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsExtensions.swift; sourceTree = ""; }; + A6BB134E25B4B2D0008C5D8A /* CloudSettingsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloudSettingsCell.swift; sourceTree = ""; }; A6E3B7E825B3260200C65157 /* Jottre.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Jottre.app; sourceTree = BUILT_PRODUCTS_DIR; }; A6E3B7EB25B3260200C65157 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; A6E3B7ED25B3260200C65157 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -66,6 +86,43 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + A6BB130525B45E52008C5D8A /* SettingsScene */ = { + isa = PBXGroup; + children = ( + A6BB130F25B46BA2008C5D8A /* SettingsNavigationViewController.swift */, + A6BB130625B45ECB008C5D8A /* SettingsViewController.swift */, + A6BB134B25B4AEFC008C5D8A /* SettingsExtensions.swift */, + ); + path = SettingsScene; + sourceTree = ""; + }; + A6BB130925B46047008C5D8A /* Node */ = { + isa = PBXGroup; + children = ( + A6E3B83325B32BBC00C65157 /* Node.swift */, + A6E3B83625B32BC500C65157 /* NodeCollector.swift */, + ); + path = Node; + sourceTree = ""; + }; + A6BB130A25B4604C008C5D8A /* Settings */ = { + isa = PBXGroup; + children = ( + A6BB130B25B46057008C5D8A /* Settings.swift */, + ); + path = Settings; + sourceTree = ""; + }; + A6BB131525B472D9008C5D8A /* SettingsCell */ = { + isa = PBXGroup; + children = ( + A6BB131225B46E2D008C5D8A /* SettingsCell.swift */, + A6BB131A25B472F9008C5D8A /* AppearanceSettingsCell.swift */, + A6BB134E25B4B2D0008C5D8A /* CloudSettingsCell.swift */, + ); + path = SettingsCell; + sourceTree = ""; + }; A6E3B7DF25B3260200C65157 = { isa = PBXGroup; children = ( @@ -96,6 +153,7 @@ A6E3B7F425B3260300C65157 /* Assets.xcassets */, A6E3B7F625B3260300C65157 /* LaunchScreen.storyboard */, A6E3B7F925B3260300C65157 /* Info.plist */, + A6BB134325B49FDF008C5D8A /* Localizable.strings */, ); path = Jottre; sourceTree = ""; @@ -106,6 +164,7 @@ A6E3B82B25B32AEB00C65157 /* NavigationViewController.swift */, A6E3B84925B347AE00C65157 /* DrawScene */, A6E3B83F25B3349900C65157 /* InitialScene */, + A6BB130525B45E52008C5D8A /* SettingsScene */, ); path = Controllers; sourceTree = ""; @@ -113,8 +172,10 @@ A6E3B80F25B3295200C65157 /* Views */ = { isa = PBXGroup; children = ( - A6E3B82725B32AD300C65157 /* NavigationButton.swift */, + A6BB131525B472D9008C5D8A /* SettingsCell */, A6E3B83925B333EC00C65157 /* NodeCell.swift */, + A6E3B82725B32AD300C65157 /* NavigationButton.swift */, + A6BB134725B4A469008C5D8A /* SettingsButton.swift */, ); path = Views; sourceTree = ""; @@ -133,8 +194,8 @@ A6E3B83225B32BAF00C65157 /* Models */ = { isa = PBXGroup; children = ( - A6E3B83325B32BBC00C65157 /* Node.swift */, - A6E3B83625B32BC500C65157 /* NodeCollector.swift */, + A6BB130A25B4604C008C5D8A /* Settings */, + A6BB130925B46047008C5D8A /* Node */, ); path = Models; sourceTree = ""; @@ -208,6 +269,7 @@ knownRegions = ( en, Base, + de, ); mainGroup = A6E3B7DF25B3260200C65157; productRefGroup = A6E3B7E925B3260200C65157 /* Products */; @@ -225,6 +287,7 @@ buildActionMask = 2147483647; files = ( A6E3B7F825B3260300C65157 /* LaunchScreen.storyboard in Resources */, + A6BB134125B49FDF008C5D8A /* Localizable.strings in Resources */, A6E3B7F525B3260300C65157 /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -240,17 +303,25 @@ A6E3B7EC25B3260200C65157 /* AppDelegate.swift in Sources */, A6E3B84125B334AF00C65157 /* InitialExtensions.swift in Sources */, A6E3B85225B34ACB00C65157 /* ThumbnailGenerator.swift in Sources */, + A6BB134825B4A469008C5D8A /* SettingsButton.swift in Sources */, A6E3B82C25B32AEB00C65157 /* NavigationViewController.swift in Sources */, + A6BB130725B45ECB008C5D8A /* SettingsViewController.swift in Sources */, A6E3B84E25B3495800C65157 /* DrawExtensions.swift in Sources */, A6E3B83D25B3340300C65157 /* UIView.swift in Sources */, A6E3B84B25B347C100C65157 /* DrawViewController.swift in Sources */, A6E3B85E25B3673C00C65157 /* UIDevice.swift in Sources */, + A6BB131325B46E2D008C5D8A /* SettingsCell.swift in Sources */, A6E3B7EE25B3260200C65157 /* SceneDelegate.swift in Sources */, A6E3B83425B32BBC00C65157 /* Node.swift in Sources */, A6E3B82F25B32B0700C65157 /* InitialViewController.swift in Sources */, A6E3B83A25B333EC00C65157 /* NodeCell.swift in Sources */, + A6BB131B25B472F9008C5D8A /* AppearanceSettingsCell.swift in Sources */, A6E3B83725B32BC500C65157 /* NodeCollector.swift in Sources */, A6E3B82425B32ABE00C65157 /* String.swift in Sources */, + A6BB130C25B46057008C5D8A /* Settings.swift in Sources */, + A6BB134F25B4B2D0008C5D8A /* CloudSettingsCell.swift in Sources */, + A6BB134C25B4AEFC008C5D8A /* SettingsExtensions.swift in Sources */, + A6BB131025B46BA2008C5D8A /* SettingsNavigationViewController.swift in Sources */, A6E3B82825B32AD300C65157 /* NavigationButton.swift in Sources */, A6E3B86825B374A200C65157 /* MenuActions.swift in Sources */, A6E3B82125B32AB400C65157 /* Logger.swift in Sources */, @@ -260,10 +331,20 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ + A6BB134325B49FDF008C5D8A /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + A6BB134225B49FDF008C5D8A /* en */, + A6BB134525B49FE0008C5D8A /* de */, + ); + name = Localizable.strings; + sourceTree = ""; + }; A6E3B7F625B3260300C65157 /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( A6E3B7F725B3260300C65157 /* Base */, + A6BB134025B49F81008C5D8A /* de */, ); name = LaunchScreen.storyboard; sourceTree = ""; @@ -275,6 +356,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; @@ -336,6 +418,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; diff --git a/Jottre/Controllers/DrawScene/DrawViewController.swift b/Jottre/Controllers/DrawScene/DrawViewController.swift index 85d0b49..8d06f31 100644 --- a/Jottre/Controllers/DrawScene/DrawViewController.swift +++ b/Jottre/Controllers/DrawScene/DrawViewController.swift @@ -163,7 +163,7 @@ class DrawViewController: UIViewController { @objc func exportDrawing() { - let alertController = UIAlertController(title: "Export note", message: "", preferredStyle: .actionSheet) + let alertController = UIAlertController(title: NSLocalizedString("Export note", comment: ""), message: "", preferredStyle: .actionSheet) if let popoverController = alertController.popoverPresentationController { popoverController.barButtonItem = navigationItem.rightBarButtonItem @@ -173,7 +173,7 @@ class DrawViewController: UIViewController { alertController.addAction(createExportToJPGAction()) alertController.addAction(createExportToPNGAction()) alertController.addAction(createShareAction()) - alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) + alertController.addAction(UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel, handler: nil)) present(alertController, animated: true, completion: nil) diff --git a/Jottre/Controllers/DrawScene/ExportActions.swift b/Jottre/Controllers/DrawScene/ExportActions.swift index 24fcb6f..68af24d 100644 --- a/Jottre/Controllers/DrawScene/ExportActions.swift +++ b/Jottre/Controllers/DrawScene/ExportActions.swift @@ -73,7 +73,7 @@ extension DrawViewController { } func createShareAction() -> UIAlertAction { - return UIAlertAction(title: "Share", style: .default, handler: { (action) in + return UIAlertAction(title: NSLocalizedString("Share", comment: ""), style: .default, handler: { (action) in self.node.push() diff --git a/Jottre/Controllers/InitialScene/MenuActions.swift b/Jottre/Controllers/InitialScene/MenuActions.swift index f5c70e0..96efc5c 100644 --- a/Jottre/Controllers/InitialScene/MenuActions.swift +++ b/Jottre/Controllers/InitialScene/MenuActions.swift @@ -11,26 +11,38 @@ import os.log extension InitialViewController { func createEditAction(indexPath: IndexPath) -> UIAction { - return UIAction(title: "Edit", image: UIImage(systemName: "square.and.pencil")) { (action) in + + let localizedAlertActionTitle = NSLocalizedString("Edit", comment: "") + + return UIAction(title: localizedAlertActionTitle, image: UIImage(systemName: "square.and.pencil")) { (action) in self.collectionView.delegate?.collectionView?(self.collectionView, didSelectItemAt: indexPath) } } func createRenameAction(indexPath: IndexPath) -> UIAction { - return UIAction(title: "Rename", image: UIImage(systemName: "rectangle.and.pencil.and.ellipsis")) { (action) in + + let localizedAlertTitle = NSLocalizedString("Rename note", comment: "") + + let localizedAlertMessage = NSLocalizedString("Enter a name for the selected note", comment: "") + + let localizedAlertPrimaryActionTitle = NSLocalizedString("Rename", comment: "") + + let localizedAlertSecondaryActionTitle = NSLocalizedString("Cancel", comment: "") + + return UIAction(title: localizedAlertPrimaryActionTitle, image: UIImage(systemName: "rectangle.and.pencil.and.ellipsis")) { (action) in guard let currentName = self.nodeCollector.nodes[indexPath.row].name, let url = self.nodeCollector.nodes[indexPath.row].url else { return } - let alertController = UIAlertController(title: "Rename note", message: "Type in a new name for the selected note", preferredStyle: .alert) + let alertController = UIAlertController(title: localizedAlertTitle, message: localizedAlertMessage, preferredStyle: .alert) alertController.addTextField { (textField) in textField.placeholder = currentName } - alertController.addAction(UIAlertAction(title: "Rename", style: UIAlertAction.Style.default, handler: { (action) in + alertController.addAction(UIAlertAction(title: localizedAlertPrimaryActionTitle, style: UIAlertAction.Style.default, handler: { (action) in guard let textFields = alertController.textFields, var updatedName = textFields[0].text else { return @@ -40,7 +52,7 @@ extension InitialViewController { self.nodeCollector.nodes[indexPath.row].rename(to: NodeCollector.computeCopyName(baseName: updatedName, path: url.deletingLastPathComponent())) })) - alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) + alertController.addAction(UIAlertAction(title: localizedAlertSecondaryActionTitle, style: .cancel, handler: nil)) self.present(alertController, animated: true, completion: nil) @@ -49,7 +61,7 @@ extension InitialViewController { func createDeleteAction(indexPath: IndexPath) -> UIMenu { - let (title, image) = ("Delete", UIImage(systemName: "trash")) + let (title, image) = (NSLocalizedString("Delete", comment: ""), UIImage(systemName: "trash")) let confirmDeleteAction = UIAction(title: "\(title)?", image: image, attributes: .destructive) { (action) in diff --git a/Jottre/Controllers/NavigationViewController.swift b/Jottre/Controllers/NavigationViewController.swift index 17d2a56..0e256c4 100644 --- a/Jottre/Controllers/NavigationViewController.swift +++ b/Jottre/Controllers/NavigationViewController.swift @@ -33,7 +33,7 @@ class NavigationViewController: UINavigationController { func setupViews() { - navigationItem.title = "My notes" + navigationItem.title = "Jottre" navigationBar.prefersLargeTitles = true view.backgroundColor = .white diff --git a/Jottre/Models/Node.swift b/Jottre/Models/Node/Node.swift similarity index 98% rename from Jottre/Models/Node.swift rename to Jottre/Models/Node/Node.swift index 3094ead..10e4c2b 100644 --- a/Jottre/Models/Node.swift +++ b/Jottre/Models/Node/Node.swift @@ -45,7 +45,7 @@ class Node: NSObject { var collector: NodeCollector? - private var serializationQueue = DispatchQueue(label: "SerializationQueue", qos: .background) + private var serializationQueue = DispatchQueue(label: "NodeSerializationQueue", qos: .background) diff --git a/Jottre/Models/NodeCollector.swift b/Jottre/Models/Node/NodeCollector.swift similarity index 98% rename from Jottre/Models/NodeCollector.swift rename to Jottre/Models/Node/NodeCollector.swift index 35de796..837735c 100644 --- a/Jottre/Models/NodeCollector.swift +++ b/Jottre/Models/Node/NodeCollector.swift @@ -166,7 +166,7 @@ class NodeCollector { while true { if FileManager.default.fileExists(atPath: currentPath.path) { - newName = "\(newName) (copy)" + newName = "\(newName) " + NSLocalizedString("(copy)", comment: "") currentPath = currentPath.deletingLastPathComponent().appendingPathComponent(newName).appendingPathExtension("jot") continue } diff --git a/Jottre/Models/Settings/Settings.swift b/Jottre/Models/Settings/Settings.swift new file mode 100644 index 0000000..108738f --- /dev/null +++ b/Jottre/Models/Settings/Settings.swift @@ -0,0 +1,105 @@ +// +// Settings.swift +// Jottre +// +// Created by Anton Lorani on 17.01.21. +// + +import Foundation +import os.log + +struct SettingsCodable: Codable { + + var usesCloud: Bool = false + + var language: Int = 0 + + var preferedAppearance: Int = 0 + +} + + +class Settings: NSObject { + + // MARK: - Properties + + var settingsCodable: SettingsCodable! + + var url: URL? { + return URL(string: "") + } + + private var serializationQueue = DispatchQueue(label: "SettingsSerializationQueue", qos: .background) + + + + // MARK: - Init + + override init() { + super.init() + pull() + } + + + + // MARK: - Methods + + /// Loading Settings from file + /// - Parameter completion: Returns a boolean that indicates success or failure + func pull(completion: ((Bool) -> Void)? = nil) { + + serializationQueue.async { + + guard let url = self.url else { + return + } + + guard FileManager.default.fileExists(atPath: url.path) else { + Logger.main.debug("File \(url.path) does not exist") + completion?(false) + return + } + + do { + let decoder = PropertyListDecoder() + let data = try Data(contentsOf: url) + self.settingsCodable = try decoder.decode(SettingsCodable.self, from: data) + } catch { + Logger.main.error("Could not read node from file: \(url.path)") + completion?(false) + } + + completion?(true) + + } + + } + + + /// Writing Settings to file + /// - Parameter completion: Returns a boolean that indicates success or failure + func push(completion: ((Bool) -> Void)? = nil) { + + serializationQueue.async { + + guard let settingsCodable = self.settingsCodable, let url = self.url else { + completion?(false) + return + } + + do { + let encoder = PropertyListEncoder() + let data = try encoder.encode(settingsCodable) + try data.write(to: url) + } catch { + Logger.main.error("Could not write NodeCodable to file: \(error.localizedDescription)") + completion?(false) + } + + completion?(true) + + } + + } + +} diff --git a/Jottre/de.lproj/LaunchScreen.strings b/Jottre/de.lproj/LaunchScreen.strings new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Jottre/de.lproj/LaunchScreen.strings @@ -0,0 +1 @@ + diff --git a/Jottre/de.lproj/Localizable.strings b/Jottre/de.lproj/Localizable.strings new file mode 100644 index 0000000..315dab7 --- /dev/null +++ b/Jottre/de.lproj/Localizable.strings @@ -0,0 +1,63 @@ +/* + Localizable.strings + Jottre + + Created by Anton Lorani on 17.01.21. + + German + +*/ + +/// - Alert + +"Cancel" = "Abbrechen"; + + +/// - Files + +"My note" = "Meine Notiz"; + +"(copy)" = "(Kopie)"; + + + +/// - Actions + +"Export note" = "Exportieren"; + +"Add note" = "Hinzufügen"; + + +"Share" = "Teilen"; + +"Create" = "Erstellen"; + +"Delete" = "Löschen"; + +"Rename" = "Umbenennen"; + +"Edit" = "Bearbeiten"; + + + +/// - Create alert + +"New note" = "Neue Notiz"; + +"Enter a name for the new note" = "Gebe einen Namen für die neue Notiz ein"; + + + +/// - Rename alert + +"Rename note" = "Notiz neubenennen"; + +"Enter a name for the selected note" = "Gebe einen neuen Namen für die neue Notiz ein"; + + + +/// - Info View + +"No documents available yet. Click 'Add note' to create a new file." = "Noch keine Dokumente vorhanden. Klicke auf 'Hinzufügen', um eine neue Datei zu erstellen."; + +"Documents created with the 'Jottre for iPad' App can be viewed here." = "Dokumente die mit der 'Jottre for iPad' App erstellt wurden, werden hier angezeigt."; diff --git a/Jottre/en.lproj/Localizable.strings b/Jottre/en.lproj/Localizable.strings new file mode 100644 index 0000000..89adebd --- /dev/null +++ b/Jottre/en.lproj/Localizable.strings @@ -0,0 +1,63 @@ +/* + Localizable.strings + Jottre + + Created by Anton Lorani on 17.01.21. + + German + +*/ + +/// - Alert + +"Cancel" = "Cancel"; + + +/// - Files + +"My note" = "My note"; + +"(copy)" = "(copy)"; + + + +/// - Actions + +"Export note" = "Export note"; + +"Add note" = "Add note"; + + +"Share" = "Share"; + +"Create" = "Create"; + +"Delete" = "Delete"; + +"Rename" = "Rename"; + +"Edit" = "Edit"; + + + +/// - Create alert + +"New note" = "New note"; + +"Enter a name for the new note" = "Enter a name for the new note"; + + + +/// - Rename alert + +"Rename note" = "Rename note"; + +"Enter a name for the selected note" = "Enter a name for the selected note"; + + + +/// - Info View + +"No documents available yet. Click 'Add note' to create a new file." = "No documents available yet. Click 'Add note' to create a new file."; + +"Documents created with the 'Jottre for iPad' App can be viewed here." = "Documents created with the 'Jottre for iPad' App can be viewed here.";