From 40ca86c0fd47901cfd0742a3950e00894fe73a60 Mon Sep 17 00:00:00 2001 From: Mark Howard Date: Tue, 4 Jul 2023 20:43:32 +0100 Subject: [PATCH 1/2] Updated macOS Project With Newer APIs --- .../Note.it/Note.it.xcodeproj/project.pbxproj | 39 + .../xcshareddata/swiftpm/Package.resolved | 14 + Source Code/Note.it/Note.it/ContentView.swift | 263 +++- Source Code/Note.it/Note.it/Note_itApp.swift | 282 +++- .../Note.it/Note.it/SettingsView.swift | 1317 ++++++++++++++++- 5 files changed, 1909 insertions(+), 6 deletions(-) create mode 100644 Source Code/Note.it/Note.it.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/Source Code/Note.it/Note.it.xcodeproj/project.pbxproj b/Source Code/Note.it/Note.it.xcodeproj/project.pbxproj index e8c9d40..f115c73 100644 --- a/Source Code/Note.it/Note.it.xcodeproj/project.pbxproj +++ b/Source Code/Note.it/Note.it.xcodeproj/project.pbxproj @@ -9,6 +9,8 @@ /* Begin PBXBuildFile section */ D5498DCD2A48B0FF00C1ECFD /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5498DCC2A48B0FF00C1ECFD /* SettingsView.swift */; }; D5498DCF2A48B11100C1ECFD /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = D5498DCE2A48B11100C1ECFD /* Settings.bundle */; }; + D55937B42A4C8640008F1AEF /* CodeMirror-SwiftUI in Frameworks */ = {isa = PBXBuildFile; productRef = D55937B32A4C8640008F1AEF /* CodeMirror-SwiftUI */; }; + D55937B52A4C869E008F1AEF /* CodeMirror-SwiftUI in Embed Frameworks */ = {isa = PBXBuildFile; productRef = D55937B32A4C8640008F1AEF /* CodeMirror-SwiftUI */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; D5677FC92A40EE1900112692 /* Note_itApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5677FC82A40EE1900112692 /* Note_itApp.swift */; }; D5677FCB2A40EE1900112692 /* Note_itDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5677FCA2A40EE1900112692 /* Note_itDocument.swift */; }; D5677FCD2A40EE1900112692 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5677FCC2A40EE1900112692 /* ContentView.swift */; }; @@ -22,6 +24,20 @@ D5677FEC2A41016B00112692 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D5677FEB2A41016B00112692 /* Preview Assets.xcassets */; }; /* End PBXBuildFile section */ +/* Begin PBXCopyFilesBuildPhase section */ + D55937A82A48D15D008F1AEF /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + D55937B52A4C869E008F1AEF /* CodeMirror-SwiftUI in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + /* Begin PBXFileReference section */ D5498DCC2A48B0FF00C1ECFD /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = ""; }; D5498DCE2A48B11100C1ECFD /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; }; @@ -48,6 +64,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D55937B42A4C8640008F1AEF /* CodeMirror-SwiftUI in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -135,6 +152,7 @@ D5677FC12A40EE1900112692 /* Sources */, D5677FC22A40EE1900112692 /* Frameworks */, D5677FC32A40EE1900112692 /* Resources */, + D55937A82A48D15D008F1AEF /* Embed Frameworks */, ); buildRules = ( ); @@ -142,6 +160,7 @@ ); name = Note.it; packageProductDependencies = ( + D55937B32A4C8640008F1AEF /* CodeMirror-SwiftUI */, ); productName = Note.it; productReference = D5677FC52A40EE1900112692 /* Note.it.app */; @@ -192,6 +211,7 @@ ); mainGroup = D5677FBC2A40EE1900112692; packageReferences = ( + D55937B22A4C8640008F1AEF /* XCRemoteSwiftPackageReference "CodeMirror-SwiftUI" */, ); productRefGroup = D5677FC62A40EE1900112692 /* Products */; projectDirPath = ""; @@ -532,6 +552,25 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + D55937B22A4C8640008F1AEF /* XCRemoteSwiftPackageReference "CodeMirror-SwiftUI" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/Pictarine/CodeMirror-SwiftUI.git"; + requirement = { + branch = master; + kind = branch; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + D55937B32A4C8640008F1AEF /* CodeMirror-SwiftUI */ = { + isa = XCSwiftPackageProductDependency; + package = D55937B22A4C8640008F1AEF /* XCRemoteSwiftPackageReference "CodeMirror-SwiftUI" */; + productName = "CodeMirror-SwiftUI"; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = D5677FBD2A40EE1900112692 /* Project object */; } diff --git a/Source Code/Note.it/Note.it.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Source Code/Note.it/Note.it.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..6795e20 --- /dev/null +++ b/Source Code/Note.it/Note.it.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,14 @@ +{ + "pins" : [ + { + "identity" : "codemirror-swiftui", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Pictarine/CodeMirror-SwiftUI.git", + "state" : { + "branch" : "master", + "revision" : "91eb30d2ea54c136de2540cacaeb95b9ab5de8e0" + } + } + ], + "version" : 2 +} diff --git a/Source Code/Note.it/Note.it/ContentView.swift b/Source Code/Note.it/Note.it/ContentView.swift index e924253..349e90a 100644 --- a/Source Code/Note.it/Note.it/ContentView.swift +++ b/Source Code/Note.it/Note.it/ContentView.swift @@ -6,17 +6,274 @@ // import SwiftUI +import AppKit +import CodeMirror_SwiftUI struct ContentView: View { @Binding var document: Note_itDocument - + @State var editor = EditorSettings() + @State var themes = ThemeSettings() + private let fileByteCountFormatter: ByteCountFormatter = { + let bcf = ByteCountFormatter() + bcf.allowedUnits = [.useAll] + bcf.countStyle = .file + return bcf + }() + @State var fileURL: URL + @State var fileTypeAttribute: String + @State var fileSizeAttribute: Int64 + @State var fileTitleAtribute: String + @State var fileCreatedAttribute: Date + @State var fileModifiedAttribute: Date + @State var fileExtensionAttribute: String + @State var fileOwnerAttribute: String + @State var filePathAttribute: String + @AppStorage("selectedAppearance") var selectedAppearance = 3 var body: some View { - TextEditor(text: $document.text) + NavigationSplitView { + List { + Section { + Text("\(NSDocumentController().currentDocument?.displayName ?? "None")") + } header: { + Label("Title", systemImage: "textformat") + } + .collapsible(false) + Section { + Text("\(fileExtensionAttribute)") + } header: { + Label("Extension", systemImage: "square.grid.3x1.folder.badge.plus") + } + .collapsible(false) + Section { + Text("\(fileByteCountFormatter.string(fromByteCount: fileSizeAttribute))") + } header: { + Label("Size", systemImage: "externaldrive") + } + .collapsible(false) + Section { + Text("\(filePathAttribute)") + } header: { + Label("Path", systemImage: "point.topleft.down.curvedto.point.bottomright.up") + } + .collapsible(false) + Section { + Text("\(fileOwnerAttribute)") + } header: { + Label("Owner", systemImage: "person") + } + .collapsible(false) + Section { + Text("\(fileCreatedAttribute.formatted(.dateTime))") + } header: { + Label("Created", systemImage: "calendar.badge.plus") + } + .collapsible(false) + Section { + Text("\(fileModifiedAttribute.formatted(.dateTime))") + } header: { + Label("Modified", systemImage: "calendar.badge.clock") + } + .collapsible(false) + Section { + Text("\(fileTypeAttribute)") + } header: { + Label("File Type", systemImage: "doc") + } + .collapsible(false) + } + .frame(minWidth: 250) + } detail: { + GeometryReader { reader in + ScrollView { + CodeView(theme: themes.theme, code: $document.text, mode: themes.syntax.mode(), fontSize: editor.fontSize, showInvisibleCharacters: editor.showInvisibleCharacters, lineWrapping: editor.lineWrapping) + .onLoadSuccess { + fileURL = NSDocumentController().currentDocument?.fileURL ?? URL(string: "/")! + getAttributes() + } + .onLoadFail { error in + print("Load Failed: \(error.localizedDescription)") + } + .onContentChange { change in + fileURL = NSDocumentController().currentDocument?.fileURL ?? URL(string: "/")! + getAttributes() + } + .frame(height: reader.size.height) + } + .frame(height: reader.size.height) + } + .toolbar(id: "quick-actions") { + ToolbarItem(id: "update-metadata", placement: .status) { + Button(action: { + fileURL = NSDocumentController().currentDocument?.fileURL ?? URL(string: "/")! + getAttributes() + }) { + Label("Update Metadata", systemImage: "arrow.counterclockwise") + } + .help("Update Metadata") + } + ToolbarItem(id: "change-appearance", placement: .status) { + Menu { + Button(action: {selectedAppearance = 1}) { + Text("Light") + } + Button(action: {selectedAppearance = 2}) { + Text("Dark") + } + Button(action: {selectedAppearance = 3}) { + Text("System") + } + } label: { + Label("Appearance", systemImage: "cloud.sun") + } + .help("Change Appearance") + } + ToolbarItem(id: "new-doc", placement: .secondaryAction) { + Button(action: {NSDocumentController().newDocument(Any?.self)}) { + Label("New", systemImage: "doc.badge.plus") + } + .help("New Document") + } + ToolbarItem(id: "open-doc", placement: .secondaryAction) { + Button(action: {NSDocumentController().openDocument(Any?.self)}) { + Label("Open", systemImage: "doc.badge.arrow.up") + } + .help("Open Document") + } + ToolbarItem(id: "save-doc", placement: .secondaryAction) { + Button(action: {NSApp.sendAction(#selector(NSDocument.save(_:)), to: nil, from: self)}) { + Label("Save", systemImage: "square.and.arrow.down") + } + .help("Save Document") + } + ToolbarItem(id: "copy-doc", placement: .secondaryAction) { + Button(action: {copyToClipBoard(textToCopy: document.text)}) { + Label("Copy", systemImage: "text.badge.plus") + } + .help("Copy Text") + } + ToolbarItem(id: "move-doc", placement: .secondaryAction) { + Button(action: {NSApp.sendAction(#selector(NSDocument.move(_:)), to: nil, from: self)}) { + Label("Move", systemImage: "folder") + } + .help("Move Document") + } + ToolbarItem(id: "duplicate-doc", placement: .secondaryAction) { + Button(action: {NSApp.sendAction(#selector(NSDocument.duplicate(_:)), to: nil, from: self)}) { + Label("Duplicate", systemImage: "doc.on.doc") + } + .help("Duplicate Document") + } + } + .toolbarRole(.editor) + } + .touchBar { + Button(action: { + fileURL = NSDocumentController().currentDocument?.fileURL ?? URL(string: "/")! + getAttributes() + }) { + Label("Metadata", systemImage: "arrow.counterclockwise") + } + Button(action: {NSDocumentController().newDocument(Any?.self)}) { + Label("New", systemImage: "doc.badge.plus") + } + Button(action: {NSDocumentController().openDocument(Any?.self)}) { + Label("Open", systemImage: "doc.badge.arrow.up") + } + Button(action: {NSApp.sendAction(#selector(NSDocument.save(_:)), to: nil, from: self)}) { + Label("Save", systemImage: "square.and.arrow.down") + } + Button(action: {copyToClipBoard(textToCopy: document.text)}) { + Label("Copy", systemImage: "text.badge.plus") + } + Button(action: {NSApp.sendAction(#selector(NSDocument.move(_:)), to: nil, from: self)}) { + Label("Move", systemImage: "folder") + } + Button(action: {NSApp.sendAction(#selector(NSDocument.duplicate(_:)), to: nil, from: self)}) { + Label("Duplicate", systemImage: "doc.on.doc") + } + } + .onAppear() { + if selectedAppearance == 1 { + NSApp.appearance = NSAppearance(named: .aqua) + } else if selectedAppearance == 2 { + NSApp.appearance = NSAppearance(named: .darkAqua) + } else { + NSApp.appearance = nil + } + fileURL = NSDocumentController().currentDocument?.fileURL ?? URL(string: "/")! + getAttributes() + } + .onChange(of: selectedAppearance) { appearance in + if selectedAppearance == 1 { + NSApp.appearance = NSAppearance(named: .aqua) + } else if selectedAppearance == 2 { + NSApp.appearance = NSAppearance(named: .darkAqua) + } else { + NSApp.appearance = nil + } + } + } + func getAttributes() { + let creationDate = fileURL.creationDate + let modificationDate = fileURL.modificationDate + let type = fileURL.fileType + let owner = fileURL.fileOwner + let size = fileURL.fileSize + let fileextension = fileURL.pathExtension + let filePath = fileURL.path + filePathAttribute = filePath + fileExtensionAttribute = fileextension + fileSizeAttribute = Int64(size) + fileOwnerAttribute = owner + fileTypeAttribute = type + fileModifiedAttribute = modificationDate! + fileCreatedAttribute = creationDate! + } + private func copyToClipBoard(textToCopy: String) { + let pasteBoard = NSPasteboard.general + pasteBoard.clearContents() + pasteBoard.setString(textToCopy, forType: .string) + } } struct ContentView_Previews: PreviewProvider { static var previews: some View { - ContentView(document: .constant(Note_itDocument())) + ContentView(document: .constant(Note_itDocument()), fileURL: URL(string: "/")!, fileTypeAttribute: "", fileSizeAttribute: 0, fileTitleAtribute: "", fileCreatedAttribute: Date(), fileModifiedAttribute: Date(), fileExtensionAttribute: "", fileOwnerAttribute: "", filePathAttribute: "") + } +} + +extension URL { + var attributes: [FileAttributeKey : Any]? { + do { + return try FileManager.default.attributesOfItem(atPath: path) + } catch let error as NSError { + print("FileAttribute error: \(error)") + } + return nil + } + + var fileSize: UInt64 { + return attributes?[.size] as? UInt64 ?? UInt64(0) + } + + var fileSizeString: String { + return ByteCountFormatter.string(fromByteCount: Int64(fileSize), countStyle: .file) + } + + var creationDate: Date? { + return attributes?[.creationDate] as? Date + } + + var fileType: String { + return attributes?[.type] as? String ?? "" + } + + var modificationDate: Date? { + return attributes?[.modificationDate] as? Date + } + + var fileOwner: String { + return attributes?[.ownerAccountName] as? String ?? "" } } diff --git a/Source Code/Note.it/Note.it/Note_itApp.swift b/Source Code/Note.it/Note.it/Note_itApp.swift index 6bb0990..4eec819 100644 --- a/Source Code/Note.it/Note.it/Note_itApp.swift +++ b/Source Code/Note.it/Note.it/Note_itApp.swift @@ -11,7 +11,287 @@ import SwiftUI struct Note_itApp: App { var body: some Scene { DocumentGroup(newDocument: Note_itDocument()) { file in - ContentView(document: file.$document) + ContentView(document: file.$document, fileURL: URL(string: "/")!, fileTypeAttribute: "N/A", fileSizeAttribute: 0, fileTitleAtribute: "N/A", fileCreatedAttribute: Date(), fileModifiedAttribute: Date(), fileExtensionAttribute: "N/A", fileOwnerAttribute: "N/A", filePathAttribute: "N/A") + .frame(minWidth: 850, minHeight: 400) + .focusedSceneValue(\.document, file.$document) + } + .commands { + SidebarCommands() + ToolbarCommands() + CommandGroup(replacing: .importExport) { + ExportCommandView() + } + } + Settings { + SettingsView() + .frame(width: 600, height: 400) + } + } +} + +struct ExportCommandView: View { + @FocusedBinding(\.document) var document + @State var isShowingSwiftSourceExport = false + @State var isShowingPlainTextExport = false + @State var isShowingXMLExport = false + @State var isShowingYAMLExport = false + @State var isShowingJSONExport = false + @State var isShowingHTMLExport = false + @State var isShowingAssemblyExport = false + @State var isShowingCHeaderExport = false + @State var isShowingCSourceExport = false + @State var isShowingCPlusPlusHeaderExport = false + @State var isShowingCPlusPlusSourceExport = false + @State var isShowingObjectiveCPlusPlusSourceExport = false + @State var isShowingObjectiveCSourceExport = false + @State var isShowingAppleScriptExport = false + @State var isShowingJavaScriptExport = false + @State var isShowingShellScriptExport = false + @State var isShowingPythonScriptExport = false + @State var isShowingRubyScriptExport = false + @State var isShowingPerlScriptExport = false + @State var isShowingPHPScriptExport = false + var body: some View { + Menu("Export As") { + Group { + Button(action: {isShowingSwiftSourceExport.toggle()}) { + Text("Swift") + } + .fileExporter(isPresented: $isShowingSwiftSourceExport, document: document, contentType: .swiftSource, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingPlainTextExport.toggle()}) { + Text("Plain Text") + } + .fileExporter(isPresented: $isShowingPlainTextExport, document: document, contentType: .plainText, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingXMLExport.toggle()}) { + Text("XML") + } + .fileExporter(isPresented: $isShowingXMLExport, document: document, contentType: .xml, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingYAMLExport.toggle()}) { + Text("YAML") + } + .fileExporter(isPresented: $isShowingYAMLExport, document: document, contentType: .yaml, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingJSONExport.toggle()}) { + Text("JSON") + } + .fileExporter(isPresented: $isShowingJSONExport, document: document, contentType: .json, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingHTMLExport.toggle()}) { + Text("HTML") + } + .fileExporter(isPresented: $isShowingHTMLExport, document: document, contentType: .html, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingAssemblyExport.toggle()}) { + Text("Assembly") + } + .fileExporter(isPresented: $isShowingAssemblyExport, document: document, contentType: .assemblyLanguageSource, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingCHeaderExport.toggle()}) { + Text("C Header") + } + .fileExporter(isPresented: $isShowingCHeaderExport, document: document, contentType: .cHeader, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingCSourceExport.toggle()}) { + Text("C Source") + } + .fileExporter(isPresented: $isShowingCSourceExport, document: document, contentType: .cSource, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingCPlusPlusHeaderExport.toggle()}) { + Text("C++ Header") + } + .fileExporter(isPresented: $isShowingCPlusPlusHeaderExport, document: document, contentType: .cPlusPlusHeader, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + } + Group { + Button(action: {isShowingCPlusPlusSourceExport.toggle()}) { + Text("C++ Source") + } + .fileExporter(isPresented: $isShowingCPlusPlusSourceExport, document: document, contentType: .cPlusPlusSource, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingObjectiveCPlusPlusSourceExport.toggle()}) { + Text("Objective C++") + } + .fileExporter(isPresented: $isShowingObjectiveCPlusPlusSourceExport, document: document, contentType: .objectiveCPlusPlusSource, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingObjectiveCSourceExport.toggle()}) { + Text("Objective C") + } + .fileExporter(isPresented: $isShowingObjectiveCSourceExport, document: document, contentType: .objectiveCSource, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingAppleScriptExport.toggle()}) { + Text("AppleScript") + } + .fileExporter(isPresented: $isShowingAppleScriptExport, document: document, contentType: .appleScript, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingJavaScriptExport.toggle()}) { + Text("JavaScript") + } + .fileExporter(isPresented: $isShowingJavaScriptExport, document: document, contentType: .javaScript, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingShellScriptExport.toggle()}) { + Text("Shell Script") + } + .fileExporter(isPresented: $isShowingShellScriptExport, document: document, contentType: .shellScript, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingPythonScriptExport.toggle()}) { + Text("Python") + } + .fileExporter(isPresented: $isShowingPythonScriptExport, document: document, contentType: .pythonScript, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingRubyScriptExport.toggle()}) { + Text("Ruby") + } + .fileExporter(isPresented: $isShowingRubyScriptExport, document: document, contentType: .rubyScript, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingPerlScriptExport.toggle()}) { + Text("Perl") + } + .fileExporter(isPresented: $isShowingPerlScriptExport, document: document, contentType: .perlScript, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingPHPScriptExport.toggle()}) { + Text("PHP") + } + .fileExporter(isPresented: $isShowingPHPScriptExport, document: document, contentType: .phpScript, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + } + } + } +} + +extension FocusedValues { + struct DocumentFocusedValues: FocusedValueKey { + typealias Value = Binding + } + + var document: Binding? { + get { + self[DocumentFocusedValues.self] + } + set { + self[DocumentFocusedValues.self] = newValue } } } diff --git a/Source Code/Note.it/Note.it/SettingsView.swift b/Source Code/Note.it/Note.it/SettingsView.swift index 9b75594..881d96c 100644 --- a/Source Code/Note.it/Note.it/SettingsView.swift +++ b/Source Code/Note.it/Note.it/SettingsView.swift @@ -6,10 +6,1323 @@ // import SwiftUI +import CodeMirror_SwiftUI struct SettingsView: View { + @State var tabSelection = 1 var body: some View { - Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + TabView(selection: $tabSelection) { + EditorSettings() + .tabItem { + Image(systemName: "pencil") + Text("Editor") + } + .tag(1) + ThemeSettings() + .tabItem { + Image(systemName: "moon") + Text("Themes") + } + .tag(2) + misc + .tabItem { + Image(systemName: "ellipsis.circle") + Text("Misc.") + } + .tag(3) + } + } + var misc: some View { + Form { + GroupBox(label: Label("Info", systemImage: "info.circle")) { + VStack { + HStack { + Spacer() + Text("Version - 2.0") + Spacer() + } + HStack { + Spacer() + Text("Build - 5") + Spacer() + } + } + } + GroupBox(label: Label("Feedback", systemImage: "questionmark.bubble")) { + VStack { + HStack { + Spacer() + Text("Want To Send Some Feedback About The App?") + Spacer() + } + HStack { + Spacer() + Button(action: {SendEmail.send()}) { + Text("Send Feedback") + } + Spacer() + } + } + } + } + .padding(.all) + } +} + +struct ThemeSettings: View { + @AppStorage("selectedSyntax") var selectedSyntax = 51 + @AppStorage("selectedTheme") var selectedTheme = 80 + @AppStorage("syntax") var syntax: CodeMode = CodeMode.text + @AppStorage("theme") var theme: CodeViewTheme = CodeViewTheme.zenburnesque + var body: some View { + Form { + CodeView(theme: theme, code: .constant("Hello World"), mode: syntax.mode(), fontSize: 12, showInvisibleCharacters: false, lineWrapping: false) + .padding(.bottom) + Picker(selection: $selectedTheme, label: Text("Theme")) { + Group { + Group { + Button(action: {}) { + Text("BB Edit") + } + .tag(1) + Button(action: {}) { + Text("All Hallow Eve") + } + .tag(2) + Button(action: {}) { + Text("Idle Fingers") + } + .tag(3) + Button(action: {}) { + Text("Space Cadet") + } + .tag(4) + Button(action: {}) { + Text("Idle") + } + .tag(5) + Button(action: {}) { + Text("Oceanic") + } + .tag(6) + Button(action: {}) { + Text("Clouds") + } + .tag(7) + Button(action: {}) { + Text("GitHub") + } + .tag(8) + Button(action: {}) { + Text("Ryan Light") + } + .tag(9) + Button(action: {}) { + Text("Black Pearl") + } + .tag(10) + } + Group { + Button(action: {}) { + Text("Mono Industrial") + } + .tag(11) + Button(action: {}) { + Text("Happy Happy Joy Joy 2") + } + .tag(12) + Button(action: {}) { + Text("Cube 2 Media") + } + .tag(13) + Button(action: {}) { + Text("Friendship Bracelet") + } + .tag(14) + Button(action: {}) { + Text("Classic Modififed") + } + .tag(15) + Button(action: {}) { + Text("Amy") + } + .tag(16) + Button(action: {}) { + Text("Demo") + } + .tag(17) + Button(action: {}) { + Text("R Dark") + } + .tag(18) + Button(action: {}) { + Text("Espresso") + } + .tag(19) + Button(action: {}) { + Text("Sunburst") + } + .tag(20) + } + Group { + Button(action: {}) { + Text("Made Of Code") + } + .tag(21) + Button(action: {}) { + Text("Arona") + } + .tag(22) + Button(action: {}) { + Text("Putty") + } + .tag(23) + Button(action: {}) { + Text("Night Lion") + } + .tag(24) + Button(action: {}) { + Text("Sidewalk Chalk") + } + .tag(25) + Button(action: {}) { + Text("Swyphs II") + } + .tag(26) + Button(action: {}) { + Text("I Plastic") + } + .tag(27) + Button(action: {}) { + Text("Solarized (Light)") + } + .tag(28) + Button(action: {}) { + Text("Mac Classic") + } + .tag(29) + Button(action: {}) { + Text("Pastels On Dark") + } + .tag(30) + } + Group { + Button(action: {}) { + Text("IR Black") + } + .tag(31) + Button(action: {}) { + Text("Material") + } + .tag(32) + Button(action: {}) { + Text("Monokai Fannon Edition") + } + .tag(33) + Button(action: {}) { + Text("Monokai Bright") + } + .tag(34) + Button(action: {}) { + Text("Eiffel") + } + .tag(35) + Button(action: {}) { + Text("Base 16 Light") + } + .tag(36) + Button(action: {}) { + Text("Oceanic Muted") + } + .tag(37) + Button(action: {}) { + Text("Summer Fruit") + } + .tag(38) + Button(action: {}) { + Text("Espresso Libre") + } + .tag(39) + Button(action: {}) { + Text("KR Theme") + } + .tag(40) + } + Group { + Button(action: {}) { + Text("Mreq") + } + .tag(41) + Button(action: {}) { + Text("Chanfle") + } + .tag(42) + Button(action: {}) { + Text("Venom") + } + .tag(43) + Button(action: {}) { + Text("Juicy") + } + .tag(44) + Button(action: {}) { + Text("Coda") + } + .tag(45) + Button(action: {}) { + Text("Fluid Vision") + } + .tag(46) + Button(action: {}) { + Text("Tomorrow Night Blue") + } + .tag(47) + Button(action: {}) { + Text("Migucwb (Amiga)") + } + .tag(48) + Button(action: {}) { + Text("Twilight") + } + .tag(49) + Button(action: {}) { + Text("Vibrant Ink") + } + .tag(50) + } + Group { + Button(action: {}) { + Text("Summer Sun") + } + .tag(51) + Button(action: {}) { + Text("Monokai") + } + .tag(52) + Button(action: {}) { + Text("Rails Envy") + } + .tag(53) + Button(action: {}) { + Text("Merbivore") + } + .tag(54) + Button(action: {}) { + Text("Dracula") + } + .tag(55) + Button(action: {}) { + Text("Pastie") + } + .tag(56) + Button(action: {}) { + Text("Low Light") + } + .tag(57) + Button(action: {}) { + Text("Spectacular") + } + .tag(58) + Button(action: {}) { + Text("Smoothy") + } + .tag(59) + Button(action: {}) { + Text("Vibrant Fin") + } + .tag(60) + } + Group { + Button(action: {}) { + Text("Blackboard") + } + .tag(61) + Button(action: {}) { + Text("Slush & Poppies") + } + .tag(62) + Button(action: {}) { + Text("Freckle") + } + .tag(63) + Button(action: {}) { + Text("Fantasy Script") + } + .tag(64) + Button(action: {}) { + Text("Tomorrow Night Eighties") + } + .tag(65) + Button(action: {}) { + Text("Rhuk") + } + .tag(66) + Button(action: {}) { + Text("Toy Chest") + } + .tag(67) + Button(action: {}) { + Text("Fake") + } + .tag(68) + Button(action: {}) { + Text("Emacs Strict") + } + .tag(69) + Button(action: {}) { + Text("Merbivore Soft") + } + .tag(70) + } + Group { + Button(action: {}) { + Text("Fade To Grey") + } + .tag(71) + Button(action: {}) { + Text("Monokai Sublime") + } + .tag(72) + Button(action: {}) { + Text("Johnny") + } + .tag(73) + Button(action: {}) { + Text("Railscasts") + } + .tag(74) + Button(action: {}) { + Text("Argonaut") + } + .tag(75) + Button(action: {}) { + Text("Tomorrow Night Bright") + } + .tag(76) + Button(action: {}) { + Text("Lazy") + } + .tag(77) + Button(action: {}) { + Text("Tomorrow Night") + } + .tag(78) + Button(action: {}) { + Text("Bongzilla") + } + .tag(79) + Button(action: {}) { + Text("Zenburnesque") + } + .tag(80) + } + Group { + Button(action: {}) { + Text("Notebook") + } + .tag(81) + Button(action: {}) { + Text("Django (Smoothy)") + } + .tag(82) + Button(action: {}) { + Text("Blackboard Black") + } + .tag(83) + Button(action: {}) { + Text("Black Pearl II") + } + .tag(84) + Button(action: {}) { + Text("Kuroir") + } + .tag(85) + Button(action: {}) { + Text("Cobalt") + } + .tag(86) + Button(action: {}) { + Text("Ayu-Mirage") + } + .tag(87) + Button(action: {}) { + Text("Chrome DevTools") + } + .tag(88) + Button(action: {}) { + Text("Prospettiva") + } + .tag(89) + Button(action: {}) { + Text("Espresso Soda") + } + .tag(90) + } + Group { + Button(action: {}) { + Text("Birds Of Paradise") + } + .tag(91) + Button(action: {}) { + Text("Text Ex Machina") + } + .tag(92) + Button(action: {}) { + Text("Django") + } + .tag(93) + Button(action: {}) { + Text("Tomorrow") + } + .tag(94) + Button(action: {}) { + Text("Solarized (Dark)") + } + .tag(95) + Button(action: {}) { + Text("Plastic Code Wrap") + } + .tag(96) + Button(action: {}) { + Text("Material Palenight") + } + .tag(97) + Button(action: {}) { + Text("Bespin") + } + .tag(98) + Button(action: {}) { + Text("Espresso Tutti") + } + .tag(99) + Button(action: {}) { + Text("Vibrant Tango") + } + .tag(100) + } + } + Group { + Button(action: {}) { + Text("Tubster") + } + .tag(101) + Button(action: {}) { + Text("Dark Pastel") + } + .tag(102) + Button(action: {}) { + Text("Dawn") + } + .tag(103) + Button(action: {}) { + Text("Tango") + } + .tag(104) + Button(action: {}) { + Text("Clouds Midnight") + } + .tag(105) + Button(action: {}) { + Text("Glitterbomb") + } + .tag(106) + Button(action: {}) { + Text("IR White") + } + .tag(107) + } + } + .pickerStyle(.menu) + .onChange(of: selectedTheme) { themeValue in + if themeValue == 1 { + self.theme = CodeViewTheme.bbedit + } + if themeValue == 2 { + self.theme = CodeViewTheme.allHallowEve + } + if themeValue == 3 { + self.theme = CodeViewTheme.idleFingers + } + if themeValue == 4 { + self.theme = CodeViewTheme.spaceCadet + } + if themeValue == 5 { + self.theme = CodeViewTheme.idle + } + if themeValue == 6 { + self.theme = CodeViewTheme.oceanic + } + if themeValue == 7 { + self.theme = CodeViewTheme.clouds + } + if themeValue == 8 { + self.theme = CodeViewTheme.github + } + if themeValue == 9 { + self.theme = CodeViewTheme.ryanLight + } + if themeValue == 10 { + self.theme = CodeViewTheme.blackPearl + } + if themeValue == 11 { + self.theme = CodeViewTheme.monoIndustrial + } + if themeValue == 12 { + self.theme = CodeViewTheme.happyHappyJoyJoy2 + } + if themeValue == 13 { + self.theme = CodeViewTheme.cube2Media + } + if themeValue == 14 { + self.theme = CodeViewTheme.friendshipBracelet + } + if themeValue == 15 { + self.theme = CodeViewTheme.classicModified + } + if themeValue == 16 { + self.theme = CodeViewTheme.amy + } + if themeValue == 17 { + self.theme = CodeViewTheme.default + } + if themeValue == 18 { + self.theme = CodeViewTheme.rdrak + } + if themeValue == 19 { + self.theme = CodeViewTheme.espresso + } + if themeValue == 20 { + self.theme = CodeViewTheme.sunburst + } + if themeValue == 21 { + self.theme = CodeViewTheme.madeOfCode + } + if themeValue == 22 { + self.theme = CodeViewTheme.arona + } + if themeValue == 23 { + self.theme = CodeViewTheme.putty + } + if themeValue == 24 { + self.theme = CodeViewTheme.nightlion + } + if themeValue == 25 { + self.theme = CodeViewTheme.sidewalkchalk + } + if themeValue == 26 { + self.theme = CodeViewTheme.swyphsii + } + if themeValue == 27 { + self.theme = CodeViewTheme.iplastic + } + if themeValue == 28 { + self.theme = CodeViewTheme.solarizedLight + } + if themeValue == 29 { + self.theme = CodeViewTheme.macClassic + } + if themeValue == 30 { + self.theme = CodeViewTheme.pastelsOnDark + } + if themeValue == 31 { + self.theme = CodeViewTheme.irBlack + } + if themeValue == 32 { + self.theme = CodeViewTheme.material + } + if themeValue == 33 { + self.theme = CodeViewTheme.monokaiFannonedition + } + if themeValue == 34 { + self.theme = CodeViewTheme.monokaiBright + } + if themeValue == 35 { + self.theme = CodeViewTheme.eiffel + } + if themeValue == 36 { + self.theme = CodeViewTheme.base16Light + } + if themeValue == 37 { + self.theme = CodeViewTheme.oceanicMuted + } + if themeValue == 38 { + self.theme = CodeViewTheme.summerfruit + } + if themeValue == 39 { + self.theme = CodeViewTheme.espressoLibre + } + if themeValue == 40 { + self.theme = CodeViewTheme.krtheme + } + if themeValue == 41 { + self.theme = CodeViewTheme.mreq + } + if themeValue == 42 { + self.theme = CodeViewTheme.chanfle + } + if themeValue == 43 { + self.theme = CodeViewTheme.venom + } + if themeValue == 44 { + self.theme = CodeViewTheme.juicy + } + if themeValue == 45 { + self.theme = CodeViewTheme.coda + } + if themeValue == 46 { + self.theme = CodeViewTheme.fluidvision + } + if themeValue == 47 { + self.theme = CodeViewTheme.tomorrowNightBlue + } + if themeValue == 48 { + self.theme = CodeViewTheme.magicwbAmiga + } + if themeValue == 49 { + self.theme = CodeViewTheme.twilight + } + if themeValue == 50 { + self.theme = CodeViewTheme.vibrantInk + } + if themeValue == 51 { + self.theme = CodeViewTheme.summerSun + } + if themeValue == 52 { + self.theme = CodeViewTheme.monokai + } + if themeValue == 53 { + self.theme = CodeViewTheme.railsEnvy + } + if themeValue == 54 { + self.theme = CodeViewTheme.merbivore + } + if themeValue == 55 { + self.theme = CodeViewTheme.dracula + } + if themeValue == 56 { + self.theme = CodeViewTheme.pastie + } + if themeValue == 57 { + self.theme = CodeViewTheme.lowlight + } + if themeValue == 58 { + self.theme = CodeViewTheme.spectacular + } + if themeValue == 59 { + self.theme = CodeViewTheme.smoothy + } + if themeValue == 60 { + self.theme = CodeViewTheme.vibrantFin + } + if themeValue == 61 { + self.theme = CodeViewTheme.blackboard + } + if themeValue == 62 { + self.theme = CodeViewTheme.slushPoppies + } + if themeValue == 63 { + self.theme = CodeViewTheme.freckle + } + if themeValue == 64 { + self.theme = CodeViewTheme.fantasyscript + } + if themeValue == 65 { + self.theme = CodeViewTheme.tomorrowNightEighties + } + if themeValue == 66 { + self.theme = CodeViewTheme.rhuk + } + if themeValue == 67 { + self.theme = CodeViewTheme.toyChest + } + if themeValue == 68 { + self.theme = CodeViewTheme.fake + } + if themeValue == 69 { + self.theme = CodeViewTheme.emacsStrict + } + if themeValue == 70 { + self.theme = CodeViewTheme.merbivoreSoft + } + if themeValue == 71 { + self.theme = CodeViewTheme.fadeToGrey + } + if themeValue == 72 { + self.theme = CodeViewTheme.monokaiSublime + } + if themeValue == 73 { + self.theme = CodeViewTheme.johnny + } + if themeValue == 74 { + self.theme = CodeViewTheme.railscasts + } + if themeValue == 75 { + self.theme = CodeViewTheme.argonaut + } + if themeValue == 76 { + self.theme = CodeViewTheme.tomorrowNightBright + } + if themeValue == 77 { + self.theme = CodeViewTheme.lazy + } + if themeValue == 78 { + self.theme = CodeViewTheme.tomorrowNight + } + if themeValue == 79 { + self.theme = CodeViewTheme.bongzilla + } + if themeValue == 80 { + self.theme = CodeViewTheme.zenburnesque + } + if themeValue == 81 { + self.theme = CodeViewTheme.notebook + } + if themeValue == 82 { + self.theme = CodeViewTheme.djangoSmoothy + } + if themeValue == 83 { + self.theme = CodeViewTheme.blackboardBlack + } + if themeValue == 84 { + self.theme = CodeViewTheme.blackPearlii + } + if themeValue == 85 { + self.theme = CodeViewTheme.kuroir + } + if themeValue == 86 { + self.theme = CodeViewTheme.cobalt + } + if themeValue == 87 { + self.theme = CodeViewTheme.ayuMirage + } + if themeValue == 88 { + self.theme = CodeViewTheme.chromeDevtools + } + if themeValue == 89 { + self.theme = CodeViewTheme.prospettiva + } + if themeValue == 90 { + self.theme = CodeViewTheme.espressoSoda + } + if themeValue == 91 { + self.theme = CodeViewTheme.birdsOfParadise + } + if themeValue == 92 { + self.theme = CodeViewTheme.textExMachina + } + if themeValue == 93 { + self.theme = CodeViewTheme.django + } + if themeValue == 94 { + self.theme = CodeViewTheme.tomorrow + } + if themeValue == 95 { + self.theme = CodeViewTheme.solarizedDark + } + if themeValue == 96 { + self.theme = CodeViewTheme.plasticcodewrap + } + if themeValue == 97 { + self.theme = CodeViewTheme.materialPalenight + } + if themeValue == 98 { + self.theme = CodeViewTheme.bespin + } + if themeValue == 99 { + self.theme = CodeViewTheme.espressoTutti + } + if themeValue == 100 { + self.theme = CodeViewTheme.vibrantTango + } + if themeValue == 101 { + self.theme = CodeViewTheme.tubster + } + if themeValue == 102 { + self.theme = CodeViewTheme.darkpastel + } + if themeValue == 103 { + self.theme = CodeViewTheme.dawn + } + if themeValue == 104 { + self.theme = CodeViewTheme.tango + } + if themeValue == 105 { + self.theme = CodeViewTheme.cloudsMidnight + } + if themeValue == 106 { + self.theme = CodeViewTheme.glitterbomb + } + if themeValue == 107 { + self.theme = CodeViewTheme.irWhite + } + } + Picker(selection: $selectedSyntax, label: Text("Syntax")) { + Group { + Button(action: {}) { + Text("APL") + } + .tag(1) + Button(action: {}) { + Text("PGP") + } + .tag(2) + Button(action: {}) { + Text("ASN") + } + .tag(3) + Button(action: {}) { + Text("C Make") + } + .tag(4) + Button(action: {}) { + Text("C") + } + .tag(5) + Button(action: {}) { + Text("C++") + } + .tag(6) + Button(action: {}) { + Text("Objective C") + } + .tag(7) + Button(action: {}) { + Text("Kotlin") + } + .tag(8) + Button(action: {}) { + Text("Scala") + } + .tag(9) + Button(action: {}) { + Text("C#") + } + .tag(10) + } + Group { + Button(action: {}) { + Text("Java") + } + .tag(11) + Button(action: {}) { + Text("Cobol") + } + .tag(12) + Button(action: {}) { + Text("Coffee Script") + } + .tag(13) + Button(action: {}) { + Text("Lisp") + } + .tag(14) + Button(action: {}) { + Text("CSS") + } + .tag(15) + Button(action: {}) { + Text("Django") + } + .tag(16) + Button(action: {}) { + Text("Docker File") + } + .tag(17) + Button(action: {}) { + Text("ERLang") + } + .tag(18) + Button(action: {}) { + Text("Fortran") + } + .tag(19) + Button(action: {}) { + Text("Go") + } + .tag(20) + } + Group { + Button(action: {}) { + Text("Groovy") + } + .tag(21) + Button(action: {}) { + Text("Haskell") + } + .tag(22) + Button(action: {}) { + Text("HTML") + } + .tag(23) + Button(action: {}) { + Text("HTTP") + } + .tag(24) + Button(action: {}) { + Text("Javascript") + } + .tag(25) + Button(action: {}) { + Text("Typescript") + } + .tag(26) + Button(action: {}) { + Text("JSON") + } + .tag(27) + Button(action: {}) { + Text("Ecma") + } + .tag(28) + Button(action: {}) { + Text("Jinja") + } + .tag(29) + Button(action: {}) { + Text("Lua") + } + .tag(30) + } + Group { + Button(action: {}) { + Text("Markdown") + } + .tag(31) + Button(action: {}) { + Text("Maths") + } + .tag(32) + Button(action: {}) { + Text("Pascal") + } + .tag(33) + Button(action: {}) { + Text("Perl") + } + .tag(34) + Button(action: {}) { + Text("PHP") + } + .tag(35) + Button(action: {}) { + Text("Powershell") + } + .tag(36) + Button(action: {}) { + Text("Properties") + } + .tag(37) + Button(action: {}) { + Text("protobuf") + } + .tag(38) + Button(action: {}) { + Text("Python") + } + .tag(39) + Button(action: {}) { + Text("R") + } + .tag(40) + } + Group { + Button(action: {}) { + Text("Ruby") + } + .tag(41) + Button(action: {}) { + Text("Rust") + } + .tag(42) + Button(action: {}) { + Text("Sass") + } + .tag(43) + Button(action: {}) { + Text("Scheme") + } + .tag(44) + Button(action: {}) { + Text("Shell") + } + .tag(45) + Button(action: {}) { + Text("SQL") + } + .tag(46) + Button(action: {}) { + Text("SQLite") + } + .tag(47) + Button(action: {}) { + Text("MySQL") + } + .tag(48) + Button(action: {}) { + Text("Latex") + } + .tag(49) + Button(action: {}) { + Text("Swift") + } + .tag(50) + } + Group { + Button(action: {}) { + Text("Text") + } + .tag(51) + Button(action: {}) { + Text("Toml") + } + .tag(52) + Button(action: {}) { + Text("VB") + } + .tag(53) + Button(action: {}) { + Text("Vue") + } + .tag(54) + Button(action: {}) { + Text("XML") + } + .tag(55) + Button(action: {}) { + Text("YAML") + } + .tag(56) + Button(action: {}) { + Text("Dart") + } + .tag(57) + Button(action: {}) { + Text("Ntriples") + } + .tag(58) + Button(action: {}) { + Text("Sparql") + } + .tag(59) + Button(action: {}) { + Text("Turtle") + } + .tag(60) + } + } + .pickerStyle(.menu) + .onChange(of: selectedSyntax) { syntax in + if syntax == 1 { + self.syntax = CodeMode.apl + } + if syntax == 2 { + self.syntax = CodeMode.pgp + } + if syntax == 3 { + self.syntax = CodeMode.asn + } + if syntax == 4 { + self.syntax = CodeMode.cmake + } + if syntax == 5 { + self.syntax = CodeMode.c + } + if syntax == 6 { + self.syntax = CodeMode.cplus + } + if syntax == 7 { + self.syntax = CodeMode.objc + } + if syntax == 8 { + self.syntax = CodeMode.kotlin + } + if syntax == 9 { + self.syntax = CodeMode.scala + } + if syntax == 10 { + self.syntax = CodeMode.csharp + } + if syntax == 11 { + self.syntax = CodeMode.java + } + if syntax == 12 { + self.syntax = CodeMode.cobol + } + if syntax == 13 { + self.syntax = CodeMode.coffeescript + } + if syntax == 14 { + self.syntax = CodeMode.lisp + } + if syntax == 15 { + self.syntax = CodeMode.css + } + if syntax == 16 { + self.syntax = CodeMode.django + } + if syntax == 17 { + self.syntax = CodeMode.dockerfile + } + if syntax == 18 { + self.syntax = CodeMode.erlang + } + if syntax == 19 { + self.syntax = CodeMode.fortran + } + if syntax == 20 { + self.syntax = CodeMode.go + } + if syntax == 21 { + self.syntax = CodeMode.groovy + } + if syntax == 22 { + self.syntax = CodeMode.haskell + } + if syntax == 23 { + self.syntax = CodeMode.html + } + if syntax == 24 { + self.syntax = CodeMode.http + } + if syntax == 25 { + self.syntax = CodeMode.javascript + } + if syntax == 26 { + self.syntax = CodeMode.typescript + } + if syntax == 27 { + self.syntax = CodeMode.json + } + if syntax == 28 { + self.syntax = CodeMode.ecma + } + if syntax == 29 { + self.syntax = CodeMode.jinja + } + if syntax == 30 { + self.syntax = CodeMode.lua + } + if syntax == 31 { + self.syntax = CodeMode.markdown + } + if syntax == 32 { + self.syntax = CodeMode.maths + } + if syntax == 33 { + self.syntax = CodeMode.pascal + } + if syntax == 34 { + self.syntax = CodeMode.perl + } + if syntax == 35 { + self.syntax = CodeMode.php + } + if syntax == 36 { + self.syntax = CodeMode.powershell + } + if syntax == 37 { + self.syntax = CodeMode.properties + } + if syntax == 38 { + self.syntax = CodeMode.protobuf + } + if syntax == 39 { + self.syntax = CodeMode.python + } + if syntax == 40 { + self.syntax = CodeMode.r + } + if syntax == 41 { + self.syntax = CodeMode.ruby + } + if syntax == 42 { + self.syntax = CodeMode.rust + } + if syntax == 43 { + self.syntax = CodeMode.sass + } + if syntax == 44 { + self.syntax = CodeMode.scheme + } + if syntax == 45 { + self.syntax = CodeMode.shell + } + if syntax == 46 { + self.syntax = CodeMode.sql + } + if syntax == 47 { + self.syntax = CodeMode.sqllite + } + if syntax == 48 { + self.syntax = CodeMode.mysql + } + if syntax == 49 { + self.syntax = CodeMode.latex + } + if syntax == 50 { + self.syntax = CodeMode.swift + } + if syntax == 51 { + self.syntax = CodeMode.text + } + if syntax == 52 { + self.syntax = CodeMode.toml + } + if syntax == 53 { + self.syntax = CodeMode.vb + } + if syntax == 54 { + self.syntax = CodeMode.vue + } + if syntax == 55 { + self.syntax = CodeMode.xml + } + if syntax == 56 { + self.syntax = CodeMode.yaml + } + if syntax == 57 { + self.syntax = CodeMode.dart + } + if syntax == 58 { + self.syntax = CodeMode.ntriples + } + if syntax == 59 { + self.syntax = CodeMode.sparql + } + if syntax == 60 { + self.syntax = CodeMode.turtle + } + } + } + .padding(.all) + } +} + +struct EditorSettings: View { + @AppStorage("lineWrapping") var lineWrapping = true + @AppStorage("showInvisibleCharacters") var showInvisibleCharacters = false + @AppStorage("fontSize") var fontSize = 12 + var body: some View { + Form { + GroupBox(label: Label("Options", systemImage: "slider.horizontal.3")) { + VStack { + HStack { + Spacer() + Stepper("Font Size - \(fontSize)", value: $fontSize, in: 1...120) + Spacer() + } + Toggle(isOn: $lineWrapping) { + Text("Line Wrapping") + } + .toggleStyle(.switch) + Toggle(isOn: $showInvisibleCharacters) { + Text("Show Invisible Characters") + } + .toggleStyle(.switch) + } + } + } + .padding(.all) } } @@ -25,6 +1338,6 @@ class SendEmail: NSObject { service.recipients = ["markhoward2005@gmail.com"] service.subject = "Note.it Feedback" - service.perform(withItems: ["Please Fill Out All Necessary Sections:", "Report A Bug - ", "Rate The App - ", "Suggest An Improvment - "]) + service.perform(withItems: ["Please Fill Out All Relevant Sections:", "Report A Bug - ", "Rate The App - ", "Suggest An Improvment - "]) } } From c729493e4f62c23abc6bcff13043f315b12ce71a Mon Sep 17 00:00:00 2001 From: Mark Howard Date: Thu, 20 Jul 2023 21:53:05 +0100 Subject: [PATCH 2/2] Added macOS Copy Text Keyboard Shortcut, Added iOS Update To APIs --- .../Note.it/Note.it iOS/ContentView.swift | 526 ++++++- .../Note.it/Note.it iOS/Note_it_iOSApp.swift | 2 +- .../Note.it/Note.it iOS/SettingsView.swift | 1313 ++++++++++++++++- .../Note.it/Note.it.xcodeproj/project.pbxproj | 48 + .../xcshareddata/swiftpm/Package.resolved | 9 + Source Code/Note.it/Note.it/ContentView.swift | 4 +- 6 files changed, 1896 insertions(+), 6 deletions(-) diff --git a/Source Code/Note.it/Note.it iOS/ContentView.swift b/Source Code/Note.it/Note.it iOS/ContentView.swift index da79e44..90c5442 100644 --- a/Source Code/Note.it/Note.it iOS/ContentView.swift +++ b/Source Code/Note.it/Note.it iOS/ContentView.swift @@ -6,17 +6,537 @@ // import SwiftUI +import UniformTypeIdentifiers +import SwiftUIPrint +import CodeMirror_SwiftUI struct ContentView: View { @Binding var document: Note_it_iOSDocument - + @Environment(\.undoManager) var undoManager + @State var editor = EditorSettings() + @State var themes = ThemesSettings() + @State var fileURL: URL + @State var fileTypeAttribute: String + @State var fileSizeAttribute: Int64 + @State var fileTitleAtribute: String + @State var fileCreatedAttribute: Date + @State var fileModifiedAttribute: Date + @State var fileExtensionAttribute: String + @State var fileOwnerAttribute: String + @State var fileNameAttribute: String + @State var filePathAttribute: String + private let fileByteCountFormatter: ByteCountFormatter = { + let bcf = ByteCountFormatter() + bcf.allowedUnits = [.useAll] + bcf.countStyle = .file + return bcf + }() + @State var showingExport = false + @State var contentTypeSelection = UTType.plainText + @State var pickerExportSelection = 1 + @State var activeSheet: ActiveSheet? + @AppStorage("selectedAppearance") var selectedAppearance = 3 + @State var isShowingSwiftSourceExport = false + @State var isShowingPlainTextExport = false + @State var isShowingXMLExport = false + @State var isShowingYAMLExport = false + @State var isShowingJSONExport = false + @State var isShowingHTMLExport = false + @State var isShowingAssemblyExport = false + @State var isShowingCHeaderExport = false + @State var isShowingCSourceExport = false + @State var isShowingCPlusPlusHeaderExport = false + @State var isShowingCPlusPlusSourceExport = false + @State var isShowingObjectiveCPlusPlusSourceExport = false + @State var isShowingObjectiveCSourceExport = false + @State var isShowingAppleScriptExport = false + @State var isShowingJavaScriptExport = false + @State var isShowingShellScriptExport = false + @State var isShowingPythonScriptExport = false + @State var isShowingRubyScriptExport = false + @State var isShowingPerlScriptExport = false + @State var isShowingPHPScriptExport = false + @State var exportAsSelection = 1 + @State var showingPrinting = false var body: some View { - TextEditor(text: $document.text) + CodeView(theme: themes.theme, code: $document.text, mode: themes.syntax.mode(), fontSize: editor.fontSize, showInvisibleCharacters: editor.showInvisibleCharacters, lineWrapping: editor.lineWrapping) + .onLoadSuccess { + getDirList() + getAttributes() + } + .onLoadFail { error in + print("Load Failed: \(error.localizedDescription)") + } + .onContentChange { change in + getDirList() + getAttributes() + } + .onAppear { + if selectedAppearance == 1 { + UIApplication.shared.keyWindow?.overrideUserInterfaceStyle = .light + } else if selectedAppearance == 2 { + UIApplication.shared.keyWindow?.overrideUserInterfaceStyle = .dark + } else { + UIApplication.shared.keyWindow?.overrideUserInterfaceStyle = .unspecified + } + } + .onChange(of: selectedAppearance) { app in + if selectedAppearance == 1 { + UIApplication.shared.keyWindow?.overrideUserInterfaceStyle = .light + } else if selectedAppearance == 2 { + UIApplication.shared.keyWindow?.overrideUserInterfaceStyle = .dark + } else { + UIApplication.shared.keyWindow?.overrideUserInterfaceStyle = .unspecified + } + } + .toolbar(id: "quick-actions") { + ToolbarItem(id: "settings", placement: .primaryAction) { + Button(action: {activeSheet = .settings}) { + Label("Settings", systemImage: "gearshape") + } + .help("Settings") + .keyboardShortcut(",") + } + ToolbarItem(id: "metadata", placement: .primaryAction) { + Button(action: {activeSheet = .metadata}) { + Label("Metadata", systemImage: "info.circle") + } + .help("Metadata") + .keyboardShortcut("i") + } + ToolbarItem(id: "export", placement: .primaryAction) { + Button(action: {activeSheet = .export}) { + Label("Export", systemImage: "square.and.arrow.up.on.square") + } + .help("Export") + .keyboardShortcut("e") + } + ToolbarItem(id: "undo", placement: .secondaryAction) { + Button(action: {undoManager?.undo()}) { + Label("Undo", systemImage: "arrow.uturn.backward") + } + .help("Undo") + } + ToolbarItem(id: "redo", placement: .secondaryAction) { + Button(action: {undoManager?.redo()}) { + Label("Redo", systemImage: "arrow.uturn.forward") + } + .help("Redo") + } + ToolbarItem(id: "change-appearance", placement: .secondaryAction) { + Menu { + Button(action: {selectedAppearance = 1}) { + Text("Light") + } + Button(action: {selectedAppearance = 2}) { + Text("Dark") + } + Button(action: {selectedAppearance = 3}) { + Text("System") + } + } label: { + Label("Appearance", systemImage: "cloud.sun") + } + .help("Change Appearance") + } + ToolbarItem(id: "copy-doc", placement: .secondaryAction) { + Button(action: {copyToClipBoard(textToCopy: document.text)}) { + Label("Copy", systemImage: "text.badge.plus") + } + .help("Copy Text") + .keyboardShortcut("c", modifiers: [.command, .shift]) + } + } + .sheet(item: $activeSheet) { item in + switch item { + case .settings: + NavigationStack { + SettingsView() + } + case .metadata: + NavigationStack { + metadata + } + case .export: + NavigationStack { + export + } + } + } + .toolbarRole(.editor) + .navigationBarTitleDisplayMode(.inline) + } + var metadata: some View { + Form { + Label("Title - \(fileNameAttribute)", systemImage: "textformat") + Label("Extension - \(fileExtensionAttribute)", systemImage: "square.grid.3x1.folder.badge.plus") + Label("Size - \(fileByteCountFormatter.string(fromByteCount: fileSizeAttribute))", systemImage: "externaldrive") + Label("Path - \(filePathAttribute)", systemImage: "point.topleft.down.curvedto.point.bottomright.up") + Label("Owner - \(fileOwnerAttribute)", systemImage: "person") + Label("Created - \(fileCreatedAttribute.formatted(.dateTime))", systemImage: "calendar.badge.plus") + Label("Modified - \(fileModifiedAttribute.formatted(.dateTime))", systemImage: "calendar.badge.clock") + Label("File Type - \(fileTypeAttribute)", systemImage: "doc") + } + .navigationTitle("Metadata") + .toolbar { + ToolbarItem(placement: .navigationBarTrailing) { + Button(action: { + getDirList() + getAttributes() + }) { + Label("Update Metadata", systemImage: "arrow.counterclockwise") + } + .help("Update Metadata") + } + } + } + var export: some View { + Form { + Group { + Button(action: {isShowingSwiftSourceExport.toggle()}) { + Text("Swift") + } + .fileExporter(isPresented: $isShowingSwiftSourceExport, document: document, contentType: .swiftSource, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingPlainTextExport.toggle()}) { + Text("Plain Text") + } + .fileExporter(isPresented: $isShowingPlainTextExport, document: document, contentType: .plainText, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingXMLExport.toggle()}) { + Text("XML") + } + .fileExporter(isPresented: $isShowingXMLExport, document: document, contentType: .xml, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingYAMLExport.toggle()}) { + Text("YAML") + } + .fileExporter(isPresented: $isShowingYAMLExport, document: document, contentType: .yaml, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingJSONExport.toggle()}) { + Text("JSON") + } + .fileExporter(isPresented: $isShowingJSONExport, document: document, contentType: .json, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingHTMLExport.toggle()}) { + Text("HTML") + } + .fileExporter(isPresented: $isShowingHTMLExport, document: document, contentType: .html, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingAssemblyExport.toggle()}) { + Text("Assembly") + } + .fileExporter(isPresented: $isShowingAssemblyExport, document: document, contentType: .assemblyLanguageSource, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingCHeaderExport.toggle()}) { + Text("C Header") + } + .fileExporter(isPresented: $isShowingCHeaderExport, document: document, contentType: .cHeader, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingCSourceExport.toggle()}) { + Text("C Source") + } + .fileExporter(isPresented: $isShowingCSourceExport, document: document, contentType: .cSource, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingCPlusPlusHeaderExport.toggle()}) { + Text("C++ Header") + } + .fileExporter(isPresented: $isShowingCPlusPlusHeaderExport, document: document, contentType: .cPlusPlusHeader, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + } + Group { + Button(action: {isShowingCPlusPlusSourceExport.toggle()}) { + Text("C++ Source") + } + .fileExporter(isPresented: $isShowingCPlusPlusSourceExport, document: document, contentType: .cPlusPlusSource, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingObjectiveCPlusPlusSourceExport.toggle()}) { + Text("Objective C++") + } + .fileExporter(isPresented: $isShowingObjectiveCPlusPlusSourceExport, document: document, contentType: .objectiveCPlusPlusSource, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingObjectiveCSourceExport.toggle()}) { + Text("Objective C") + } + .fileExporter(isPresented: $isShowingObjectiveCSourceExport, document: document, contentType: .objectiveCSource, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingAppleScriptExport.toggle()}) { + Text("AppleScript") + } + .fileExporter(isPresented: $isShowingAppleScriptExport, document: document, contentType: .appleScript, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingJavaScriptExport.toggle()}) { + Text("JavaScript") + } + .fileExporter(isPresented: $isShowingJavaScriptExport, document: document, contentType: .javaScript, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingShellScriptExport.toggle()}) { + Text("Shell Script") + } + .fileExporter(isPresented: $isShowingShellScriptExport, document: document, contentType: .shellScript, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingPythonScriptExport.toggle()}) { + Text("Python") + } + .fileExporter(isPresented: $isShowingPythonScriptExport, document: document, contentType: .pythonScript, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingRubyScriptExport.toggle()}) { + Text("Ruby") + } + .fileExporter(isPresented: $isShowingRubyScriptExport, document: document, contentType: .rubyScript, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingPerlScriptExport.toggle()}) { + Text("Perl") + } + .fileExporter(isPresented: $isShowingPerlScriptExport, document: document, contentType: .perlScript, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + Button(action: {isShowingPHPScriptExport.toggle()}) { + Text("PHP") + } + .fileExporter(isPresented: $isShowingPHPScriptExport, document: document, contentType: .phpScript, defaultFilename: "Exported File") { result in + switch result { + case .success(let url): + print("Saved To \(url)") + case .failure(let error): + print(error.localizedDescription) + } + } + } + } + .navigationTitle("Export") + .toolbar { + ToolbarItem(placement: .navigationBarTrailing) { + Button(action: {showingPrinting = true}) { + Image(systemName: "printer") + } + .sheet(isPresented: $showingPrinting) { + SamplePrintSetup(page: + VStack { + HStack { + Text(document.text) + Spacer() + } + Spacer() + } + .padding() + ) + } + } + } + } + func getAttributes() { + let creationDate = fileURL.creationDate + let modificationDate = fileURL.modificationDate + let type = fileURL.fileType + let owner = fileURL.fileOwner + let size = fileURL.fileSize + let fileextension = fileURL.pathExtension + let filePath = fileURL.path + let fileName = fileURL.deletingPathExtension().lastPathComponent + fileNameAttribute = fileName + filePathAttribute = filePath + fileExtensionAttribute = fileextension + fileSizeAttribute = Int64(size) + fileOwnerAttribute = owner + fileTypeAttribute = type + fileModifiedAttribute = modificationDate! + fileCreatedAttribute = creationDate! + } + func getDirList() { + let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! + guard let directoryURL = URL(string: paths.path) else { return } + do { + let contents = try FileManager.default.contentsOfDirectory(at: directoryURL, includingPropertiesForKeys:[.contentAccessDateKey], options: [.skipsHiddenFiles]) + .sorted(by: { + let date0 = try $0.promisedItemResourceValues(forKeys:[.contentAccessDateKey]).contentAccessDate! + let date1 = try $1.promisedItemResourceValues(forKeys:[.contentAccessDateKey]).contentAccessDate! + return date0.compare(date1) == .orderedAscending + }) + + for item in contents { + guard let t = try? item.promisedItemResourceValues(forKeys:[.contentAccessDateKey]).contentAccessDate else { return } + print("\(t) \(item.lastPathComponent)") + fileURL = item + } + } catch { + print(error) + } + } + private func copyToClipBoard(textToCopy: String) { + let paste = UIPasteboard.general + paste.string = textToCopy } } struct ContentView_Previews: PreviewProvider { static var previews: some View { - ContentView(document: .constant(Note_it_iOSDocument())) + ContentView(document: .constant(Note_it_iOSDocument()), fileURL: URL(string: "/")!, fileTypeAttribute: "", fileSizeAttribute: 0, fileTitleAtribute: "", fileCreatedAttribute: Date(), fileModifiedAttribute: Date(), fileExtensionAttribute: "", fileOwnerAttribute: "", fileNameAttribute: "", filePathAttribute: "") + } +} + +extension URL { + var attributes: [FileAttributeKey : Any]? { + do { + return try FileManager.default.attributesOfItem(atPath: path) + } catch let error as NSError { + print("FileAttribute Error: \(error)") + } + return nil + } + + var fileSize: UInt64 { + return attributes?[.size] as? UInt64 ?? UInt64(0) + } + + var fileSizeString: String { + return ByteCountFormatter.string(fromByteCount: Int64(fileSize), countStyle: .file) + } + + var creationDate: Date? { + return attributes?[.creationDate] as? Date + } + + var fileType: String { + return attributes?[.type] as? String ?? "" + } + + var modificationDate: Date? { + return attributes?[.modificationDate] as? Date + } + + var fileOwner: String { + return attributes?[.ownerAccountName] as? String ?? "" + } +} + +enum ActiveSheet: Identifiable { + case settings, metadata, export + + var id: Int { + hashValue + } +} + +extension UIApplication { + var keyWindow: UIWindow? { + return self.connectedScenes + .filter { $0.activationState == .foregroundActive } + .first(where: { $0 is UIWindowScene }) + .flatMap({ $0 as? UIWindowScene })?.windows + .first(where: \.isKeyWindow) } } diff --git a/Source Code/Note.it/Note.it iOS/Note_it_iOSApp.swift b/Source Code/Note.it/Note.it iOS/Note_it_iOSApp.swift index 9b86cb6..a3cfcf5 100644 --- a/Source Code/Note.it/Note.it iOS/Note_it_iOSApp.swift +++ b/Source Code/Note.it/Note.it iOS/Note_it_iOSApp.swift @@ -11,7 +11,7 @@ import SwiftUI struct Note_it_iOSApp: App { var body: some Scene { DocumentGroup(newDocument: Note_it_iOSDocument()) { file in - ContentView(document: file.$document) + ContentView(document: file.$document, fileURL: URL(string: "/")!, fileTypeAttribute: "N/A", fileSizeAttribute: 0, fileTitleAtribute: "N/A", fileCreatedAttribute: Date(), fileModifiedAttribute: Date(), fileExtensionAttribute: "N/A", fileOwnerAttribute: "N/A", fileNameAttribute: "N/A", filePathAttribute: "N/A") } } } diff --git a/Source Code/Note.it/Note.it iOS/SettingsView.swift b/Source Code/Note.it/Note.it iOS/SettingsView.swift index 70e1672..089c107 100644 --- a/Source Code/Note.it/Note.it iOS/SettingsView.swift +++ b/Source Code/Note.it/Note.it iOS/SettingsView.swift @@ -6,10 +6,33 @@ // import SwiftUI +import CodeMirror_SwiftUI +import MessageUI struct SettingsView: View { + @State var result: Result? = nil + @State var isShowingMailView = false var body: some View { - Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + Form { + EditorSettings() + ThemesSettings() + misc + } + .navigationTitle("Settings") + } + var misc: some View { + Section { + LabeledContent("Version", value: "2.0") + LabeledContent("Build", value: "5") + Button(action: {isShowingMailView.toggle()}) { + Text("Send Feedback") + } + .sheet(isPresented: $isShowingMailView) { + MailView(isShowing: self.$isShowingMailView, result: self.$result) + } + } header: { + Label("Misc.", systemImage: "info.circle") + } } } @@ -18,3 +41,1291 @@ struct SettingsView_Previews: PreviewProvider { SettingsView() } } + +struct ThemesSettings: View { + @AppStorage("selectedSyntax") var selectedSyntax = 51 + @AppStorage("selectedTheme") var selectedTheme = 80 + @AppStorage("syntax") var syntax: CodeMode = CodeMode.text + @AppStorage("theme") var theme: CodeViewTheme = CodeViewTheme.zenburnesque + var body: some View { + Section { + Picker(selection: $selectedTheme, label: Text("Theme")) { + Group { + Group { + Button(action: {}) { + Text("BB Edit") + } + .tag(1) + Button(action: {}) { + Text("All Hallow Eve") + } + .tag(2) + Button(action: {}) { + Text("Idle Fingers") + } + .tag(3) + Button(action: {}) { + Text("Space Cadet") + } + .tag(4) + Button(action: {}) { + Text("Idle") + } + .tag(5) + Button(action: {}) { + Text("Oceanic") + } + .tag(6) + Button(action: {}) { + Text("Clouds") + } + .tag(7) + Button(action: {}) { + Text("GitHub") + } + .tag(8) + Button(action: {}) { + Text("Ryan Light") + } + .tag(9) + Button(action: {}) { + Text("Black Pearl") + } + .tag(10) + } + Group { + Button(action: {}) { + Text("Mono Industrial") + } + .tag(11) + Button(action: {}) { + Text("Happy Happy Joy Joy 2") + } + .tag(12) + Button(action: {}) { + Text("Cube 2 Media") + } + .tag(13) + Button(action: {}) { + Text("Friendship Bracelet") + } + .tag(14) + Button(action: {}) { + Text("Classic Modififed") + } + .tag(15) + Button(action: {}) { + Text("Amy") + } + .tag(16) + Button(action: {}) { + Text("Demo") + } + .tag(17) + Button(action: {}) { + Text("R Dark") + } + .tag(18) + Button(action: {}) { + Text("Espresso") + } + .tag(19) + Button(action: {}) { + Text("Sunburst") + } + .tag(20) + } + Group { + Button(action: {}) { + Text("Made Of Code") + } + .tag(21) + Button(action: {}) { + Text("Arona") + } + .tag(22) + Button(action: {}) { + Text("Putty") + } + .tag(23) + Button(action: {}) { + Text("Night Lion") + } + .tag(24) + Button(action: {}) { + Text("Sidewalk Chalk") + } + .tag(25) + Button(action: {}) { + Text("Swyphs II") + } + .tag(26) + Button(action: {}) { + Text("I Plastic") + } + .tag(27) + Button(action: {}) { + Text("Solarized (Light)") + } + .tag(28) + Button(action: {}) { + Text("Mac Classic") + } + .tag(29) + Button(action: {}) { + Text("Pastels On Dark") + } + .tag(30) + } + Group { + Button(action: {}) { + Text("IR Black") + } + .tag(31) + Button(action: {}) { + Text("Material") + } + .tag(32) + Button(action: {}) { + Text("Monokai Fannon Edition") + } + .tag(33) + Button(action: {}) { + Text("Monokai Bright") + } + .tag(34) + Button(action: {}) { + Text("Eiffel") + } + .tag(35) + Button(action: {}) { + Text("Base 16 Light") + } + .tag(36) + Button(action: {}) { + Text("Oceanic Muted") + } + .tag(37) + Button(action: {}) { + Text("Summer Fruit") + } + .tag(38) + Button(action: {}) { + Text("Espresso Libre") + } + .tag(39) + Button(action: {}) { + Text("KR Theme") + } + .tag(40) + } + Group { + Button(action: {}) { + Text("Mreq") + } + .tag(41) + Button(action: {}) { + Text("Chanfle") + } + .tag(42) + Button(action: {}) { + Text("Venom") + } + .tag(43) + Button(action: {}) { + Text("Juicy") + } + .tag(44) + Button(action: {}) { + Text("Coda") + } + .tag(45) + Button(action: {}) { + Text("Fluid Vision") + } + .tag(46) + Button(action: {}) { + Text("Tomorrow Night Blue") + } + .tag(47) + Button(action: {}) { + Text("Migucwb (Amiga)") + } + .tag(48) + Button(action: {}) { + Text("Twilight") + } + .tag(49) + Button(action: {}) { + Text("Vibrant Ink") + } + .tag(50) + } + Group { + Button(action: {}) { + Text("Summer Sun") + } + .tag(51) + Button(action: {}) { + Text("Monokai") + } + .tag(52) + Button(action: {}) { + Text("Rails Envy") + } + .tag(53) + Button(action: {}) { + Text("Merbivore") + } + .tag(54) + Button(action: {}) { + Text("Dracula") + } + .tag(55) + Button(action: {}) { + Text("Pastie") + } + .tag(56) + Button(action: {}) { + Text("Low Light") + } + .tag(57) + Button(action: {}) { + Text("Spectacular") + } + .tag(58) + Button(action: {}) { + Text("Smoothy") + } + .tag(59) + Button(action: {}) { + Text("Vibrant Fin") + } + .tag(60) + } + Group { + Button(action: {}) { + Text("Blackboard") + } + .tag(61) + Button(action: {}) { + Text("Slush & Poppies") + } + .tag(62) + Button(action: {}) { + Text("Freckle") + } + .tag(63) + Button(action: {}) { + Text("Fantasy Script") + } + .tag(64) + Button(action: {}) { + Text("Tomorrow Night Eighties") + } + .tag(65) + Button(action: {}) { + Text("Rhuk") + } + .tag(66) + Button(action: {}) { + Text("Toy Chest") + } + .tag(67) + Button(action: {}) { + Text("Fake") + } + .tag(68) + Button(action: {}) { + Text("Emacs Strict") + } + .tag(69) + Button(action: {}) { + Text("Merbivore Soft") + } + .tag(70) + } + Group { + Button(action: {}) { + Text("Fade To Grey") + } + .tag(71) + Button(action: {}) { + Text("Monokai Sublime") + } + .tag(72) + Button(action: {}) { + Text("Johnny") + } + .tag(73) + Button(action: {}) { + Text("Railscasts") + } + .tag(74) + Button(action: {}) { + Text("Argonaut") + } + .tag(75) + Button(action: {}) { + Text("Tomorrow Night Bright") + } + .tag(76) + Button(action: {}) { + Text("Lazy") + } + .tag(77) + Button(action: {}) { + Text("Tomorrow Night") + } + .tag(78) + Button(action: {}) { + Text("Bongzilla") + } + .tag(79) + Button(action: {}) { + Text("Zenburnesque") + } + .tag(80) + } + Group { + Button(action: {}) { + Text("Notebook") + } + .tag(81) + Button(action: {}) { + Text("Django (Smoothy)") + } + .tag(82) + Button(action: {}) { + Text("Blackboard Black") + } + .tag(83) + Button(action: {}) { + Text("Black Pearl II") + } + .tag(84) + Button(action: {}) { + Text("Kuroir") + } + .tag(85) + Button(action: {}) { + Text("Cobalt") + } + .tag(86) + Button(action: {}) { + Text("Ayu-Mirage") + } + .tag(87) + Button(action: {}) { + Text("Chrome DevTools") + } + .tag(88) + Button(action: {}) { + Text("Prospettiva") + } + .tag(89) + Button(action: {}) { + Text("Espresso Soda") + } + .tag(90) + } + Group { + Button(action: {}) { + Text("Birds Of Paradise") + } + .tag(91) + Button(action: {}) { + Text("Text Ex Machina") + } + .tag(92) + Button(action: {}) { + Text("Django") + } + .tag(93) + Button(action: {}) { + Text("Tomorrow") + } + .tag(94) + Button(action: {}) { + Text("Solarized (Dark)") + } + .tag(95) + Button(action: {}) { + Text("Plastic Code Wrap") + } + .tag(96) + Button(action: {}) { + Text("Material Palenight") + } + .tag(97) + Button(action: {}) { + Text("Bespin") + } + .tag(98) + Button(action: {}) { + Text("Espresso Tutti") + } + .tag(99) + Button(action: {}) { + Text("Vibrant Tango") + } + .tag(100) + } + } + Group { + Button(action: {}) { + Text("Tubster") + } + .tag(101) + Button(action: {}) { + Text("Dark Pastel") + } + .tag(102) + Button(action: {}) { + Text("Dawn") + } + .tag(103) + Button(action: {}) { + Text("Tango") + } + .tag(104) + Button(action: {}) { + Text("Clouds Midnight") + } + .tag(105) + Button(action: {}) { + Text("Glitterbomb") + } + .tag(106) + Button(action: {}) { + Text("IR White") + } + .tag(107) + } + } + .pickerStyle(.menu) + .onChange(of: selectedTheme) { themeValue in + if themeValue == 1 { + self.theme = CodeViewTheme.bbedit + } + if themeValue == 2 { + self.theme = CodeViewTheme.allHallowEve + } + if themeValue == 3 { + self.theme = CodeViewTheme.idleFingers + } + if themeValue == 4 { + self.theme = CodeViewTheme.spaceCadet + } + if themeValue == 5 { + self.theme = CodeViewTheme.idle + } + if themeValue == 6 { + self.theme = CodeViewTheme.oceanic + } + if themeValue == 7 { + self.theme = CodeViewTheme.clouds + } + if themeValue == 8 { + self.theme = CodeViewTheme.github + } + if themeValue == 9 { + self.theme = CodeViewTheme.ryanLight + } + if themeValue == 10 { + self.theme = CodeViewTheme.blackPearl + } + if themeValue == 11 { + self.theme = CodeViewTheme.monoIndustrial + } + if themeValue == 12 { + self.theme = CodeViewTheme.happyHappyJoyJoy2 + } + if themeValue == 13 { + self.theme = CodeViewTheme.cube2Media + } + if themeValue == 14 { + self.theme = CodeViewTheme.friendshipBracelet + } + if themeValue == 15 { + self.theme = CodeViewTheme.classicModified + } + if themeValue == 16 { + self.theme = CodeViewTheme.amy + } + if themeValue == 17 { + self.theme = CodeViewTheme.default + } + if themeValue == 18 { + self.theme = CodeViewTheme.rdrak + } + if themeValue == 19 { + self.theme = CodeViewTheme.espresso + } + if themeValue == 20 { + self.theme = CodeViewTheme.sunburst + } + if themeValue == 21 { + self.theme = CodeViewTheme.madeOfCode + } + if themeValue == 22 { + self.theme = CodeViewTheme.arona + } + if themeValue == 23 { + self.theme = CodeViewTheme.putty + } + if themeValue == 24 { + self.theme = CodeViewTheme.nightlion + } + if themeValue == 25 { + self.theme = CodeViewTheme.sidewalkchalk + } + if themeValue == 26 { + self.theme = CodeViewTheme.swyphsii + } + if themeValue == 27 { + self.theme = CodeViewTheme.iplastic + } + if themeValue == 28 { + self.theme = CodeViewTheme.solarizedLight + } + if themeValue == 29 { + self.theme = CodeViewTheme.macClassic + } + if themeValue == 30 { + self.theme = CodeViewTheme.pastelsOnDark + } + if themeValue == 31 { + self.theme = CodeViewTheme.irBlack + } + if themeValue == 32 { + self.theme = CodeViewTheme.material + } + if themeValue == 33 { + self.theme = CodeViewTheme.monokaiFannonedition + } + if themeValue == 34 { + self.theme = CodeViewTheme.monokaiBright + } + if themeValue == 35 { + self.theme = CodeViewTheme.eiffel + } + if themeValue == 36 { + self.theme = CodeViewTheme.base16Light + } + if themeValue == 37 { + self.theme = CodeViewTheme.oceanicMuted + } + if themeValue == 38 { + self.theme = CodeViewTheme.summerfruit + } + if themeValue == 39 { + self.theme = CodeViewTheme.espressoLibre + } + if themeValue == 40 { + self.theme = CodeViewTheme.krtheme + } + if themeValue == 41 { + self.theme = CodeViewTheme.mreq + } + if themeValue == 42 { + self.theme = CodeViewTheme.chanfle + } + if themeValue == 43 { + self.theme = CodeViewTheme.venom + } + if themeValue == 44 { + self.theme = CodeViewTheme.juicy + } + if themeValue == 45 { + self.theme = CodeViewTheme.coda + } + if themeValue == 46 { + self.theme = CodeViewTheme.fluidvision + } + if themeValue == 47 { + self.theme = CodeViewTheme.tomorrowNightBlue + } + if themeValue == 48 { + self.theme = CodeViewTheme.magicwbAmiga + } + if themeValue == 49 { + self.theme = CodeViewTheme.twilight + } + if themeValue == 50 { + self.theme = CodeViewTheme.vibrantInk + } + if themeValue == 51 { + self.theme = CodeViewTheme.summerSun + } + if themeValue == 52 { + self.theme = CodeViewTheme.monokai + } + if themeValue == 53 { + self.theme = CodeViewTheme.railsEnvy + } + if themeValue == 54 { + self.theme = CodeViewTheme.merbivore + } + if themeValue == 55 { + self.theme = CodeViewTheme.dracula + } + if themeValue == 56 { + self.theme = CodeViewTheme.pastie + } + if themeValue == 57 { + self.theme = CodeViewTheme.lowlight + } + if themeValue == 58 { + self.theme = CodeViewTheme.spectacular + } + if themeValue == 59 { + self.theme = CodeViewTheme.smoothy + } + if themeValue == 60 { + self.theme = CodeViewTheme.vibrantFin + } + if themeValue == 61 { + self.theme = CodeViewTheme.blackboard + } + if themeValue == 62 { + self.theme = CodeViewTheme.slushPoppies + } + if themeValue == 63 { + self.theme = CodeViewTheme.freckle + } + if themeValue == 64 { + self.theme = CodeViewTheme.fantasyscript + } + if themeValue == 65 { + self.theme = CodeViewTheme.tomorrowNightEighties + } + if themeValue == 66 { + self.theme = CodeViewTheme.rhuk + } + if themeValue == 67 { + self.theme = CodeViewTheme.toyChest + } + if themeValue == 68 { + self.theme = CodeViewTheme.fake + } + if themeValue == 69 { + self.theme = CodeViewTheme.emacsStrict + } + if themeValue == 70 { + self.theme = CodeViewTheme.merbivoreSoft + } + if themeValue == 71 { + self.theme = CodeViewTheme.fadeToGrey + } + if themeValue == 72 { + self.theme = CodeViewTheme.monokaiSublime + } + if themeValue == 73 { + self.theme = CodeViewTheme.johnny + } + if themeValue == 74 { + self.theme = CodeViewTheme.railscasts + } + if themeValue == 75 { + self.theme = CodeViewTheme.argonaut + } + if themeValue == 76 { + self.theme = CodeViewTheme.tomorrowNightBright + } + if themeValue == 77 { + self.theme = CodeViewTheme.lazy + } + if themeValue == 78 { + self.theme = CodeViewTheme.tomorrowNight + } + if themeValue == 79 { + self.theme = CodeViewTheme.bongzilla + } + if themeValue == 80 { + self.theme = CodeViewTheme.zenburnesque + } + if themeValue == 81 { + self.theme = CodeViewTheme.notebook + } + if themeValue == 82 { + self.theme = CodeViewTheme.djangoSmoothy + } + if themeValue == 83 { + self.theme = CodeViewTheme.blackboardBlack + } + if themeValue == 84 { + self.theme = CodeViewTheme.blackPearlii + } + if themeValue == 85 { + self.theme = CodeViewTheme.kuroir + } + if themeValue == 86 { + self.theme = CodeViewTheme.cobalt + } + if themeValue == 87 { + self.theme = CodeViewTheme.ayuMirage + } + if themeValue == 88 { + self.theme = CodeViewTheme.chromeDevtools + } + if themeValue == 89 { + self.theme = CodeViewTheme.prospettiva + } + if themeValue == 90 { + self.theme = CodeViewTheme.espressoSoda + } + if themeValue == 91 { + self.theme = CodeViewTheme.birdsOfParadise + } + if themeValue == 92 { + self.theme = CodeViewTheme.textExMachina + } + if themeValue == 93 { + self.theme = CodeViewTheme.django + } + if themeValue == 94 { + self.theme = CodeViewTheme.tomorrow + } + if themeValue == 95 { + self.theme = CodeViewTheme.solarizedDark + } + if themeValue == 96 { + self.theme = CodeViewTheme.plasticcodewrap + } + if themeValue == 97 { + self.theme = CodeViewTheme.materialPalenight + } + if themeValue == 98 { + self.theme = CodeViewTheme.bespin + } + if themeValue == 99 { + self.theme = CodeViewTheme.espressoTutti + } + if themeValue == 100 { + self.theme = CodeViewTheme.vibrantTango + } + if themeValue == 101 { + self.theme = CodeViewTheme.tubster + } + if themeValue == 102 { + self.theme = CodeViewTheme.darkpastel + } + if themeValue == 103 { + self.theme = CodeViewTheme.dawn + } + if themeValue == 104 { + self.theme = CodeViewTheme.tango + } + if themeValue == 105 { + self.theme = CodeViewTheme.cloudsMidnight + } + if themeValue == 106 { + self.theme = CodeViewTheme.glitterbomb + } + if themeValue == 107 { + self.theme = CodeViewTheme.irWhite + } + } + Picker(selection: $selectedSyntax, label: Text("Syntax")) { + Group { + Button(action: {}) { + Text("APL") + } + .tag(1) + Button(action: {}) { + Text("PGP") + } + .tag(2) + Button(action: {}) { + Text("ASN") + } + .tag(3) + Button(action: {}) { + Text("C Make") + } + .tag(4) + Button(action: {}) { + Text("C") + } + .tag(5) + Button(action: {}) { + Text("C++") + } + .tag(6) + Button(action: {}) { + Text("Objective C") + } + .tag(7) + Button(action: {}) { + Text("Kotlin") + } + .tag(8) + Button(action: {}) { + Text("Scala") + } + .tag(9) + Button(action: {}) { + Text("C#") + } + .tag(10) + } + Group { + Button(action: {}) { + Text("Java") + } + .tag(11) + Button(action: {}) { + Text("Cobol") + } + .tag(12) + Button(action: {}) { + Text("Coffee Script") + } + .tag(13) + Button(action: {}) { + Text("Lisp") + } + .tag(14) + Button(action: {}) { + Text("CSS") + } + .tag(15) + Button(action: {}) { + Text("Django") + } + .tag(16) + Button(action: {}) { + Text("Docker File") + } + .tag(17) + Button(action: {}) { + Text("ERLang") + } + .tag(18) + Button(action: {}) { + Text("Fortran") + } + .tag(19) + Button(action: {}) { + Text("Go") + } + .tag(20) + } + Group { + Button(action: {}) { + Text("Groovy") + } + .tag(21) + Button(action: {}) { + Text("Haskell") + } + .tag(22) + Button(action: {}) { + Text("HTML") + } + .tag(23) + Button(action: {}) { + Text("HTTP") + } + .tag(24) + Button(action: {}) { + Text("Javascript") + } + .tag(25) + Button(action: {}) { + Text("Typescript") + } + .tag(26) + Button(action: {}) { + Text("JSON") + } + .tag(27) + Button(action: {}) { + Text("Ecma") + } + .tag(28) + Button(action: {}) { + Text("Jinja") + } + .tag(29) + Button(action: {}) { + Text("Lua") + } + .tag(30) + } + Group { + Button(action: {}) { + Text("Markdown") + } + .tag(31) + Button(action: {}) { + Text("Maths") + } + .tag(32) + Button(action: {}) { + Text("Pascal") + } + .tag(33) + Button(action: {}) { + Text("Perl") + } + .tag(34) + Button(action: {}) { + Text("PHP") + } + .tag(35) + Button(action: {}) { + Text("Powershell") + } + .tag(36) + Button(action: {}) { + Text("Properties") + } + .tag(37) + Button(action: {}) { + Text("protobuf") + } + .tag(38) + Button(action: {}) { + Text("Python") + } + .tag(39) + Button(action: {}) { + Text("R") + } + .tag(40) + } + Group { + Button(action: {}) { + Text("Ruby") + } + .tag(41) + Button(action: {}) { + Text("Rust") + } + .tag(42) + Button(action: {}) { + Text("Sass") + } + .tag(43) + Button(action: {}) { + Text("Scheme") + } + .tag(44) + Button(action: {}) { + Text("Shell") + } + .tag(45) + Button(action: {}) { + Text("SQL") + } + .tag(46) + Button(action: {}) { + Text("SQLite") + } + .tag(47) + Button(action: {}) { + Text("MySQL") + } + .tag(48) + Button(action: {}) { + Text("Latex") + } + .tag(49) + Button(action: {}) { + Text("Swift") + } + .tag(50) + } + Group { + Button(action: {}) { + Text("Text") + } + .tag(51) + Button(action: {}) { + Text("Toml") + } + .tag(52) + Button(action: {}) { + Text("VB") + } + .tag(53) + Button(action: {}) { + Text("Vue") + } + .tag(54) + Button(action: {}) { + Text("XML") + } + .tag(55) + Button(action: {}) { + Text("YAML") + } + .tag(56) + Button(action: {}) { + Text("Dart") + } + .tag(57) + Button(action: {}) { + Text("Ntriples") + } + .tag(58) + Button(action: {}) { + Text("Sparql") + } + .tag(59) + Button(action: {}) { + Text("Turtle") + } + .tag(60) + } + } + .pickerStyle(.menu) + .onChange(of: selectedSyntax) { syntax in + if syntax == 1 { + self.syntax = CodeMode.apl + } + if syntax == 2 { + self.syntax = CodeMode.pgp + } + if syntax == 3 { + self.syntax = CodeMode.asn + } + if syntax == 4 { + self.syntax = CodeMode.cmake + } + if syntax == 5 { + self.syntax = CodeMode.c + } + if syntax == 6 { + self.syntax = CodeMode.cplus + } + if syntax == 7 { + self.syntax = CodeMode.objc + } + if syntax == 8 { + self.syntax = CodeMode.kotlin + } + if syntax == 9 { + self.syntax = CodeMode.scala + } + if syntax == 10 { + self.syntax = CodeMode.csharp + } + if syntax == 11 { + self.syntax = CodeMode.java + } + if syntax == 12 { + self.syntax = CodeMode.cobol + } + if syntax == 13 { + self.syntax = CodeMode.coffeescript + } + if syntax == 14 { + self.syntax = CodeMode.lisp + } + if syntax == 15 { + self.syntax = CodeMode.css + } + if syntax == 16 { + self.syntax = CodeMode.django + } + if syntax == 17 { + self.syntax = CodeMode.dockerfile + } + if syntax == 18 { + self.syntax = CodeMode.erlang + } + if syntax == 19 { + self.syntax = CodeMode.fortran + } + if syntax == 20 { + self.syntax = CodeMode.go + } + if syntax == 21 { + self.syntax = CodeMode.groovy + } + if syntax == 22 { + self.syntax = CodeMode.haskell + } + if syntax == 23 { + self.syntax = CodeMode.html + } + if syntax == 24 { + self.syntax = CodeMode.http + } + if syntax == 25 { + self.syntax = CodeMode.javascript + } + if syntax == 26 { + self.syntax = CodeMode.typescript + } + if syntax == 27 { + self.syntax = CodeMode.json + } + if syntax == 28 { + self.syntax = CodeMode.ecma + } + if syntax == 29 { + self.syntax = CodeMode.jinja + } + if syntax == 30 { + self.syntax = CodeMode.lua + } + if syntax == 31 { + self.syntax = CodeMode.markdown + } + if syntax == 32 { + self.syntax = CodeMode.maths + } + if syntax == 33 { + self.syntax = CodeMode.pascal + } + if syntax == 34 { + self.syntax = CodeMode.perl + } + if syntax == 35 { + self.syntax = CodeMode.php + } + if syntax == 36 { + self.syntax = CodeMode.powershell + } + if syntax == 37 { + self.syntax = CodeMode.properties + } + if syntax == 38 { + self.syntax = CodeMode.protobuf + } + if syntax == 39 { + self.syntax = CodeMode.python + } + if syntax == 40 { + self.syntax = CodeMode.r + } + if syntax == 41 { + self.syntax = CodeMode.ruby + } + if syntax == 42 { + self.syntax = CodeMode.rust + } + if syntax == 43 { + self.syntax = CodeMode.sass + } + if syntax == 44 { + self.syntax = CodeMode.scheme + } + if syntax == 45 { + self.syntax = CodeMode.shell + } + if syntax == 46 { + self.syntax = CodeMode.sql + } + if syntax == 47 { + self.syntax = CodeMode.sqllite + } + if syntax == 48 { + self.syntax = CodeMode.mysql + } + if syntax == 49 { + self.syntax = CodeMode.latex + } + if syntax == 50 { + self.syntax = CodeMode.swift + } + if syntax == 51 { + self.syntax = CodeMode.text + } + if syntax == 52 { + self.syntax = CodeMode.toml + } + if syntax == 53 { + self.syntax = CodeMode.vb + } + if syntax == 54 { + self.syntax = CodeMode.vue + } + if syntax == 55 { + self.syntax = CodeMode.xml + } + if syntax == 56 { + self.syntax = CodeMode.yaml + } + if syntax == 57 { + self.syntax = CodeMode.dart + } + if syntax == 58 { + self.syntax = CodeMode.ntriples + } + if syntax == 59 { + self.syntax = CodeMode.sparql + } + if syntax == 60 { + self.syntax = CodeMode.turtle + } + } + } header: { + Label("Themes", systemImage: "moon") + } + } +} + +struct EditorSettings: View { + @AppStorage("lineWrapping") var lineWrapping = true + @AppStorage("showInvisibleCharacters") var showInvisibleCharacters = false + @AppStorage("fontSize") var fontSize = 12 + var body: some View { + Section { + Stepper("Font Size - \(fontSize)", value: $fontSize, in: 1...120) + Toggle(isOn: $lineWrapping) { + Text("Line Wrapping") + } + .toggleStyle(.switch) + Toggle(isOn: $showInvisibleCharacters) { + Text("Show Invisible Characters") + } + .toggleStyle(.switch) + } header: { + Label("Editor", systemImage: "pencil") + } + } +} + +struct MailView: UIViewControllerRepresentable { + @Binding var isShowing: Bool + @Binding var result: Result? + + class Coordinator: NSObject, MFMailComposeViewControllerDelegate { + @Binding var isShowing: Bool + @Binding var result: Result? + init(isShowing: Binding, result: Binding?>) { + _isShowing = isShowing + _result = result + } + + func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) { + defer { + isShowing = false + } + guard error == nil else { + self.result = .failure(error!) + return + } + self.result = .success(result) + } + } + + func makeCoordinator() -> Coordinator { + return Coordinator(isShowing: $isShowing, result: $result) + } + + func makeUIViewController(context: UIViewControllerRepresentableContext) -> MFMailComposeViewController { + let vc = MFMailComposeViewController() + vc.mailComposeDelegate = context.coordinator + return vc + } + + func updateUIViewController(_ uiViewController: MFMailComposeViewController, context: UIViewControllerRepresentableContext) { + + } +} diff --git a/Source Code/Note.it/Note.it.xcodeproj/project.pbxproj b/Source Code/Note.it/Note.it.xcodeproj/project.pbxproj index f115c73..3214c38 100644 --- a/Source Code/Note.it/Note.it.xcodeproj/project.pbxproj +++ b/Source Code/Note.it/Note.it.xcodeproj/project.pbxproj @@ -11,6 +11,9 @@ D5498DCF2A48B11100C1ECFD /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = D5498DCE2A48B11100C1ECFD /* Settings.bundle */; }; D55937B42A4C8640008F1AEF /* CodeMirror-SwiftUI in Frameworks */ = {isa = PBXBuildFile; productRef = D55937B32A4C8640008F1AEF /* CodeMirror-SwiftUI */; }; D55937B52A4C869E008F1AEF /* CodeMirror-SwiftUI in Embed Frameworks */ = {isa = PBXBuildFile; productRef = D55937B32A4C8640008F1AEF /* CodeMirror-SwiftUI */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; + D55937BB2A54AF46008F1AEF /* SwiftUIPrint in Frameworks */ = {isa = PBXBuildFile; productRef = D55937BA2A54AF46008F1AEF /* SwiftUIPrint */; }; + D55937BE2A54B137008F1AEF /* CodeMirror-SwiftUI in Frameworks */ = {isa = PBXBuildFile; productRef = D55937BD2A54B137008F1AEF /* CodeMirror-SwiftUI */; }; + D55937BF2A54B137008F1AEF /* CodeMirror-SwiftUI in Embed Frameworks */ = {isa = PBXBuildFile; productRef = D55937BD2A54B137008F1AEF /* CodeMirror-SwiftUI */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; D5677FC92A40EE1900112692 /* Note_itApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5677FC82A40EE1900112692 /* Note_itApp.swift */; }; D5677FCB2A40EE1900112692 /* Note_itDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5677FCA2A40EE1900112692 /* Note_itDocument.swift */; }; D5677FCD2A40EE1900112692 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5677FCC2A40EE1900112692 /* ContentView.swift */; }; @@ -36,6 +39,17 @@ name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; + D55937C02A54B137008F1AEF /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + D55937BF2A54B137008F1AEF /* CodeMirror-SwiftUI in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -72,18 +86,28 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D55937BE2A54B137008F1AEF /* CodeMirror-SwiftUI in Frameworks */, + D55937BB2A54AF46008F1AEF /* SwiftUIPrint in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + D55937BC2A54B137008F1AEF /* Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = Frameworks; + sourceTree = ""; + }; D5677FBC2A40EE1900112692 = { isa = PBXGroup; children = ( D5677FC72A40EE1900112692 /* Note.it */, D5677FE12A41016A00112692 /* Note.it iOS */, D5677FC62A40EE1900112692 /* Products */, + D55937BC2A54B137008F1AEF /* Frameworks */, ); sourceTree = ""; }; @@ -173,12 +197,17 @@ D5677FDC2A41016A00112692 /* Sources */, D5677FDD2A41016A00112692 /* Frameworks */, D5677FDE2A41016A00112692 /* Resources */, + D55937C02A54B137008F1AEF /* Embed Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "Note.it iOS"; + packageProductDependencies = ( + D55937BA2A54AF46008F1AEF /* SwiftUIPrint */, + D55937BD2A54B137008F1AEF /* CodeMirror-SwiftUI */, + ); productName = "Note.it iOS"; productReference = D5677FE02A41016A00112692 /* Note.it iOS.app */; productType = "com.apple.product-type.application"; @@ -212,6 +241,7 @@ mainGroup = D5677FBC2A40EE1900112692; packageReferences = ( D55937B22A4C8640008F1AEF /* XCRemoteSwiftPackageReference "CodeMirror-SwiftUI" */, + D55937B92A54AF46008F1AEF /* XCRemoteSwiftPackageReference "SwiftUIPrint" */, ); productRefGroup = D5677FC62A40EE1900112692 /* Products */; projectDirPath = ""; @@ -562,6 +592,14 @@ kind = branch; }; }; + D55937B92A54AF46008F1AEF /* XCRemoteSwiftPackageReference "SwiftUIPrint" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/wolfmcnally/SwiftUIPrint.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 2.0.0; + }; + }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -570,6 +608,16 @@ package = D55937B22A4C8640008F1AEF /* XCRemoteSwiftPackageReference "CodeMirror-SwiftUI" */; productName = "CodeMirror-SwiftUI"; }; + D55937BA2A54AF46008F1AEF /* SwiftUIPrint */ = { + isa = XCSwiftPackageProductDependency; + package = D55937B92A54AF46008F1AEF /* XCRemoteSwiftPackageReference "SwiftUIPrint" */; + productName = SwiftUIPrint; + }; + D55937BD2A54B137008F1AEF /* CodeMirror-SwiftUI */ = { + isa = XCSwiftPackageProductDependency; + package = D55937B22A4C8640008F1AEF /* XCRemoteSwiftPackageReference "CodeMirror-SwiftUI" */; + productName = "CodeMirror-SwiftUI"; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = D5677FBD2A40EE1900112692 /* Project object */; diff --git a/Source Code/Note.it/Note.it.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Source Code/Note.it/Note.it.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 6795e20..f66614b 100644 --- a/Source Code/Note.it/Note.it.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Source Code/Note.it/Note.it.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -8,6 +8,15 @@ "branch" : "master", "revision" : "91eb30d2ea54c136de2540cacaeb95b9ab5de8e0" } + }, + { + "identity" : "swiftuiprint", + "kind" : "remoteSourceControl", + "location" : "https://github.com/wolfmcnally/SwiftUIPrint.git", + "state" : { + "revision" : "06e1953ceff40c08a0e899e604658f2c38358c3e", + "version" : "2.0.1" + } } ], "version" : 2 diff --git a/Source Code/Note.it/Note.it/ContentView.swift b/Source Code/Note.it/Note.it/ContentView.swift index 349e90a..1d5be50 100644 --- a/Source Code/Note.it/Note.it/ContentView.swift +++ b/Source Code/Note.it/Note.it/ContentView.swift @@ -110,6 +110,7 @@ struct ContentView: View { Label("Update Metadata", systemImage: "arrow.counterclockwise") } .help("Update Metadata") + .keyboardShortcut("r") } ToolbarItem(id: "change-appearance", placement: .status) { Menu { @@ -150,6 +151,7 @@ struct ContentView: View { Label("Copy", systemImage: "text.badge.plus") } .help("Copy Text") + .keyboardShortcut("c", modifiers: [.command, .shift]) } ToolbarItem(id: "move-doc", placement: .secondaryAction) { Button(action: {NSApp.sendAction(#selector(NSDocument.move(_:)), to: nil, from: self)}) { @@ -248,7 +250,7 @@ extension URL { do { return try FileManager.default.attributesOfItem(atPath: path) } catch let error as NSError { - print("FileAttribute error: \(error)") + print("FileAttribute Error: \(error)") } return nil }