mirror of
https://github.com/XcodesOrg/XcodesApp.git
synced 2026-03-25 08:55:46 +00:00
Add custom about window with dependency acknowledgments
This commit is contained in:
parent
8c5ae40b1e
commit
cb42864d44
16 changed files with 884 additions and 418 deletions
|
|
@ -13,6 +13,9 @@
|
||||||
CA5D781E257365D6008EDE9D /* PinCodeTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA5D781D257365D6008EDE9D /* PinCodeTextView.swift */; };
|
CA5D781E257365D6008EDE9D /* PinCodeTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA5D781D257365D6008EDE9D /* PinCodeTextView.swift */; };
|
||||||
CA735109257BF96D00EA9CF8 /* AttributedText.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA735108257BF96D00EA9CF8 /* AttributedText.swift */; };
|
CA735109257BF96D00EA9CF8 /* AttributedText.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA735108257BF96D00EA9CF8 /* AttributedText.swift */; };
|
||||||
CA73510D257BFCEF00EA9CF8 /* NSAttributedString+.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA73510C257BFCEF00EA9CF8 /* NSAttributedString+.swift */; };
|
CA73510D257BFCEF00EA9CF8 /* NSAttributedString+.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA73510C257BFCEF00EA9CF8 /* NSAttributedString+.swift */; };
|
||||||
|
CA9FF83F2594FBC000E47BAF /* Licenses.rtf in Resources */ = {isa = PBXBuildFile; fileRef = CA9FF83E2594FBC000E47BAF /* Licenses.rtf */; };
|
||||||
|
CA9FF84E2595079F00E47BAF /* ScrollingTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA9FF84D2595079F00E47BAF /* ScrollingTextView.swift */; };
|
||||||
|
CA9FF8522595080100E47BAF /* AcknowledgementsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA9FF8512595080100E47BAF /* AcknowledgementsView.swift */; };
|
||||||
CAA1CB2D255A5262003FD669 /* AppleAPI in Frameworks */ = {isa = PBXBuildFile; productRef = CAA1CB2C255A5262003FD669 /* AppleAPI */; };
|
CAA1CB2D255A5262003FD669 /* AppleAPI in Frameworks */ = {isa = PBXBuildFile; productRef = CAA1CB2C255A5262003FD669 /* AppleAPI */; };
|
||||||
CAA1CB35255A5AD5003FD669 /* SignInCredentialsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAA1CB34255A5AD5003FD669 /* SignInCredentialsView.swift */; };
|
CAA1CB35255A5AD5003FD669 /* SignInCredentialsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAA1CB34255A5AD5003FD669 /* SignInCredentialsView.swift */; };
|
||||||
CAA1CB45255A5B60003FD669 /* SignIn2FAView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAA1CB44255A5B60003FD669 /* SignIn2FAView.swift */; };
|
CAA1CB45255A5B60003FD669 /* SignIn2FAView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAA1CB44255A5B60003FD669 /* SignIn2FAView.swift */; };
|
||||||
|
|
@ -41,11 +44,12 @@
|
||||||
CABFA9FD2592F13300380FEE /* LegibleError in Frameworks */ = {isa = PBXBuildFile; productRef = CABFA9FC2592F13300380FEE /* LegibleError */; };
|
CABFA9FD2592F13300380FEE /* LegibleError in Frameworks */ = {isa = PBXBuildFile; productRef = CABFA9FC2592F13300380FEE /* LegibleError */; };
|
||||||
CABFAA2C2592FBFC00380FEE /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CABFAA2A2592FBFC00380FEE /* SettingsView.swift */; };
|
CABFAA2C2592FBFC00380FEE /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CABFAA2A2592FBFC00380FEE /* SettingsView.swift */; };
|
||||||
CABFAA2D2592FBFC00380FEE /* Configure.swift in Sources */ = {isa = PBXBuildFile; fileRef = CABFAA2B2592FBFC00380FEE /* Configure.swift */; };
|
CABFAA2D2592FBFC00380FEE /* Configure.swift in Sources */ = {isa = PBXBuildFile; fileRef = CABFAA2B2592FBFC00380FEE /* Configure.swift */; };
|
||||||
|
CABFAA432593104F00380FEE /* AboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CABFAA422593104F00380FEE /* AboutView.swift */; };
|
||||||
|
CABFAA492593162500380FEE /* Bundle+InfoPlistValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = CABFAA482593162500380FEE /* Bundle+InfoPlistValues.swift */; };
|
||||||
CAD2E7A22449574E00113D76 /* XcodesApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAD2E7A12449574E00113D76 /* XcodesApp.swift */; };
|
CAD2E7A22449574E00113D76 /* XcodesApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAD2E7A12449574E00113D76 /* XcodesApp.swift */; };
|
||||||
CAD2E7A42449574E00113D76 /* XcodeListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAD2E7A32449574E00113D76 /* XcodeListView.swift */; };
|
CAD2E7A42449574E00113D76 /* XcodeListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAD2E7A32449574E00113D76 /* XcodeListView.swift */; };
|
||||||
CAD2E7A62449575000113D76 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CAD2E7A52449575000113D76 /* Assets.xcassets */; };
|
CAD2E7A62449575000113D76 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CAD2E7A52449575000113D76 /* Assets.xcassets */; };
|
||||||
CAD2E7A92449575000113D76 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CAD2E7A82449575000113D76 /* Preview Assets.xcassets */; };
|
CAD2E7A92449575000113D76 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CAD2E7A82449575000113D76 /* Preview Assets.xcassets */; };
|
||||||
CAD2E7AC2449575000113D76 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CAD2E7AA2449575000113D76 /* Main.storyboard */; };
|
|
||||||
CAD2E7B82449575100113D76 /* XcodesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAD2E7B72449575100113D76 /* XcodesTests.swift */; };
|
CAD2E7B82449575100113D76 /* XcodesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAD2E7B72449575100113D76 /* XcodesTests.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
|
@ -70,6 +74,10 @@
|
||||||
CA8FB5F8256E0F9400469DA5 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
|
CA8FB5F8256E0F9400469DA5 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
|
||||||
CA8FB61C256E115700469DA5 /* .github */ = {isa = PBXFileReference; lastKnownFileType = folder; path = .github; sourceTree = "<group>"; };
|
CA8FB61C256E115700469DA5 /* .github */ = {isa = PBXFileReference; lastKnownFileType = folder; path = .github; sourceTree = "<group>"; };
|
||||||
CA8FB64D256E17B100469DA5 /* XcodesTest.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = XcodesTest.entitlements; sourceTree = "<group>"; };
|
CA8FB64D256E17B100469DA5 /* XcodesTest.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = XcodesTest.entitlements; sourceTree = "<group>"; };
|
||||||
|
CA9FF8242594F10700E47BAF /* AcknowledgementsGenerator */ = {isa = PBXFileReference; lastKnownFileType = folder; name = AcknowledgementsGenerator; path = Xcodes/AcknowledgementsGenerator; sourceTree = "<group>"; };
|
||||||
|
CA9FF83E2594FBC000E47BAF /* Licenses.rtf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.rtf; path = Licenses.rtf; sourceTree = "<group>"; };
|
||||||
|
CA9FF84D2595079F00E47BAF /* ScrollingTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollingTextView.swift; sourceTree = "<group>"; };
|
||||||
|
CA9FF8512595080100E47BAF /* AcknowledgementsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AcknowledgementsView.swift; sourceTree = "<group>"; };
|
||||||
CAA1CB34255A5AD5003FD669 /* SignInCredentialsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignInCredentialsView.swift; sourceTree = "<group>"; };
|
CAA1CB34255A5AD5003FD669 /* SignInCredentialsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignInCredentialsView.swift; sourceTree = "<group>"; };
|
||||||
CAA1CB44255A5B60003FD669 /* SignIn2FAView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignIn2FAView.swift; sourceTree = "<group>"; };
|
CAA1CB44255A5B60003FD669 /* SignIn2FAView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignIn2FAView.swift; sourceTree = "<group>"; };
|
||||||
CAA1CB48255A5C97003FD669 /* SignInSMSView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignInSMSView.swift; sourceTree = "<group>"; };
|
CAA1CB48255A5C97003FD669 /* SignInSMSView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignInSMSView.swift; sourceTree = "<group>"; };
|
||||||
|
|
@ -94,12 +102,13 @@
|
||||||
CABFA9D42592EF6300380FEE /* DECISIONS.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = DECISIONS.md; sourceTree = "<group>"; };
|
CABFA9D42592EF6300380FEE /* DECISIONS.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = DECISIONS.md; sourceTree = "<group>"; };
|
||||||
CABFAA2A2592FBFC00380FEE /* SettingsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SettingsView.swift; path = Xcodes/SettingsView.swift; sourceTree = SOURCE_ROOT; };
|
CABFAA2A2592FBFC00380FEE /* SettingsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SettingsView.swift; path = Xcodes/SettingsView.swift; sourceTree = SOURCE_ROOT; };
|
||||||
CABFAA2B2592FBFC00380FEE /* Configure.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Configure.swift; path = Xcodes/Backend/Configure.swift; sourceTree = SOURCE_ROOT; };
|
CABFAA2B2592FBFC00380FEE /* Configure.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Configure.swift; path = Xcodes/Backend/Configure.swift; sourceTree = SOURCE_ROOT; };
|
||||||
|
CABFAA422593104F00380FEE /* AboutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutView.swift; sourceTree = "<group>"; };
|
||||||
|
CABFAA482593162500380FEE /* Bundle+InfoPlistValues.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Bundle+InfoPlistValues.swift"; sourceTree = "<group>"; };
|
||||||
CAD2E79E2449574E00113D76 /* Xcodes.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Xcodes.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
CAD2E79E2449574E00113D76 /* Xcodes.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Xcodes.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
CAD2E7A12449574E00113D76 /* XcodesApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XcodesApp.swift; sourceTree = "<group>"; };
|
CAD2E7A12449574E00113D76 /* XcodesApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XcodesApp.swift; sourceTree = "<group>"; };
|
||||||
CAD2E7A32449574E00113D76 /* XcodeListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XcodeListView.swift; sourceTree = "<group>"; };
|
CAD2E7A32449574E00113D76 /* XcodeListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XcodeListView.swift; sourceTree = "<group>"; };
|
||||||
CAD2E7A52449575000113D76 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
CAD2E7A52449575000113D76 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||||
CAD2E7A82449575000113D76 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
|
CAD2E7A82449575000113D76 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
|
||||||
CAD2E7AB2449575000113D76 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
|
||||||
CAD2E7AD2449575000113D76 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
CAD2E7AD2449575000113D76 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
CAD2E7AE2449575000113D76 /* Xcodes.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Xcodes.entitlements; sourceTree = "<group>"; };
|
CAD2E7AE2449575000113D76 /* Xcodes.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Xcodes.entitlements; sourceTree = "<group>"; };
|
||||||
CAD2E7B32449575100113D76 /* XcodesTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XcodesTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
CAD2E7B32449575100113D76 /* XcodesTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XcodesTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
|
@ -140,6 +149,16 @@
|
||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
CA9FF8552595082000E47BAF /* About */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
CABFAA422593104F00380FEE /* AboutView.swift */,
|
||||||
|
CA9FF8512595080100E47BAF /* AcknowledgementsView.swift */,
|
||||||
|
CA9FF84D2595079F00E47BAF /* ScrollingTextView.swift */,
|
||||||
|
);
|
||||||
|
path = About;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
CAA1CB50255A5D16003FD669 /* SignIn */ = {
|
CAA1CB50255A5D16003FD669 /* SignIn */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
|
@ -169,6 +188,7 @@
|
||||||
children = (
|
children = (
|
||||||
CA378F982466567600A58CE0 /* AppState.swift */,
|
CA378F982466567600A58CE0 /* AppState.swift */,
|
||||||
CABFAA2B2592FBFC00380FEE /* Configure.swift */,
|
CABFAA2B2592FBFC00380FEE /* Configure.swift */,
|
||||||
|
CABFAA482593162500380FEE /* Bundle+InfoPlistValues.swift */,
|
||||||
CABFA9BA2592EEEA00380FEE /* DateFormatter+.swift */,
|
CABFA9BA2592EEEA00380FEE /* DateFormatter+.swift */,
|
||||||
CABFA9B22592EEEA00380FEE /* Entry+.swift */,
|
CABFA9B22592EEEA00380FEE /* Entry+.swift */,
|
||||||
CABFA9A92592EEE900380FEE /* Environment.swift */,
|
CABFA9A92592EEE900380FEE /* Environment.swift */,
|
||||||
|
|
@ -190,6 +210,7 @@
|
||||||
CABFAA1A2592F7D900380FEE /* Frontend */ = {
|
CABFAA1A2592F7D900380FEE /* Frontend */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
CA9FF8552595082000E47BAF /* About */,
|
||||||
CAA1CB50255A5D16003FD669 /* SignIn */,
|
CAA1CB50255A5D16003FD669 /* SignIn */,
|
||||||
CABFAA142592F73000380FEE /* XcodeList */,
|
CABFAA142592F73000380FEE /* XcodeList */,
|
||||||
CABFAA2A2592FBFC00380FEE /* SettingsView.swift */,
|
CABFAA2A2592FBFC00380FEE /* SettingsView.swift */,
|
||||||
|
|
@ -201,8 +222,8 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
CAD2E7A52449575000113D76 /* Assets.xcassets */,
|
CAD2E7A52449575000113D76 /* Assets.xcassets */,
|
||||||
CAD2E7AA2449575000113D76 /* Main.storyboard */,
|
|
||||||
CAD2E7AD2449575000113D76 /* Info.plist */,
|
CAD2E7AD2449575000113D76 /* Info.plist */,
|
||||||
|
CA9FF83E2594FBC000E47BAF /* Licenses.rtf */,
|
||||||
CAD2E7AE2449575000113D76 /* Xcodes.entitlements */,
|
CAD2E7AE2449575000113D76 /* Xcodes.entitlements */,
|
||||||
CA8FB64D256E17B100469DA5 /* XcodesTest.entitlements */,
|
CA8FB64D256E17B100469DA5 /* XcodesTest.entitlements */,
|
||||||
);
|
);
|
||||||
|
|
@ -218,6 +239,7 @@
|
||||||
CABFA9A32592ED5700380FEE /* Apple.paw */,
|
CABFA9A32592ED5700380FEE /* Apple.paw */,
|
||||||
CABFA9A12592EAFB00380FEE /* LICENSE */,
|
CABFA9A12592EAFB00380FEE /* LICENSE */,
|
||||||
CA8FB61C256E115700469DA5 /* .github */,
|
CA8FB61C256E115700469DA5 /* .github */,
|
||||||
|
CA9FF8242594F10700E47BAF /* AcknowledgementsGenerator */,
|
||||||
CA538A0C255A4F1A00E64DD7 /* AppleAPI */,
|
CA538A0C255A4F1A00E64DD7 /* AppleAPI */,
|
||||||
CAD2E7A02449574E00113D76 /* Xcodes */,
|
CAD2E7A02449574E00113D76 /* Xcodes */,
|
||||||
CAD2E7B62449575100113D76 /* XcodesTests */,
|
CAD2E7B62449575100113D76 /* XcodesTests */,
|
||||||
|
|
@ -273,6 +295,7 @@
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
CAD2E79A2449574E00113D76 /* Sources */,
|
CAD2E79A2449574E00113D76 /* Sources */,
|
||||||
CAD2E79B2449574E00113D76 /* Frameworks */,
|
CAD2E79B2449574E00113D76 /* Frameworks */,
|
||||||
|
CA9FF8292594F33200E47BAF /* Generate Acknowledgements */,
|
||||||
CAD2E79C2449574E00113D76 /* Resources */,
|
CAD2E79C2449574E00113D76 /* Resources */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
|
|
@ -364,8 +387,8 @@
|
||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
CAD2E7AC2449575000113D76 /* Main.storyboard in Resources */,
|
|
||||||
CAD2E7A92449575000113D76 /* Preview Assets.xcassets in Resources */,
|
CAD2E7A92449575000113D76 /* Preview Assets.xcassets in Resources */,
|
||||||
|
CA9FF83F2594FBC000E47BAF /* Licenses.rtf in Resources */,
|
||||||
CAD2E7A62449575000113D76 /* Assets.xcassets in Resources */,
|
CAD2E7A62449575000113D76 /* Assets.xcassets in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
|
@ -379,12 +402,34 @@
|
||||||
};
|
};
|
||||||
/* End PBXResourcesBuildPhase section */
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXShellScriptBuildPhase section */
|
||||||
|
CA9FF8292594F33200E47BAF /* Generate Acknowledgements */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
|
name = "Generate Acknowledgements";
|
||||||
|
outputFileListPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "cd \"${SRCROOT}/Xcodes/AcknowledgementsGenerator\"\nxcrun -sdk macosx swift run AcknowledgementsGenerator \\\n -p \"${SRCROOT}/Xcodes.xcodeproj\" \\\n -o \"${SRCROOT}/Xcodes/Resources/Licenses.rtf\"\n";
|
||||||
|
};
|
||||||
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
CAD2E79A2449574E00113D76 /* Sources */ = {
|
CAD2E79A2449574E00113D76 /* Sources */ = {
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
CA735109257BF96D00EA9CF8 /* AttributedText.swift in Sources */,
|
CA735109257BF96D00EA9CF8 /* AttributedText.swift in Sources */,
|
||||||
|
CABFAA492593162500380FEE /* Bundle+InfoPlistValues.swift in Sources */,
|
||||||
CABFA9CA2592EEEA00380FEE /* XcodeList.swift in Sources */,
|
CABFA9CA2592EEEA00380FEE /* XcodeList.swift in Sources */,
|
||||||
CA44901F2463AD34003D8213 /* Tag.swift in Sources */,
|
CA44901F2463AD34003D8213 /* Tag.swift in Sources */,
|
||||||
CABFA9BF2592EEEA00380FEE /* URLSession+Promise.swift in Sources */,
|
CABFA9BF2592EEEA00380FEE /* URLSession+Promise.swift in Sources */,
|
||||||
|
|
@ -396,7 +441,9 @@
|
||||||
CAA1CB45255A5B60003FD669 /* SignIn2FAView.swift in Sources */,
|
CAA1CB45255A5B60003FD669 /* SignIn2FAView.swift in Sources */,
|
||||||
CABFA9C52592EEEA00380FEE /* FileManager+.swift in Sources */,
|
CABFA9C52592EEEA00380FEE /* FileManager+.swift in Sources */,
|
||||||
CABFA9CD2592EEEA00380FEE /* Foundation.swift in Sources */,
|
CABFA9CD2592EEEA00380FEE /* Foundation.swift in Sources */,
|
||||||
|
CA9FF84E2595079F00E47BAF /* ScrollingTextView.swift in Sources */,
|
||||||
CABFA9C12592EEEA00380FEE /* Version+.swift in Sources */,
|
CABFA9C12592EEEA00380FEE /* Version+.swift in Sources */,
|
||||||
|
CA9FF8522595080100E47BAF /* AcknowledgementsView.swift in Sources */,
|
||||||
CABFA9CE2592EEEA00380FEE /* Version+Xcode.swift in Sources */,
|
CABFA9CE2592EEEA00380FEE /* Version+Xcode.swift in Sources */,
|
||||||
CAA1CB49255A5C97003FD669 /* SignInSMSView.swift in Sources */,
|
CAA1CB49255A5C97003FD669 /* SignInSMSView.swift in Sources */,
|
||||||
CAA1CB35255A5AD5003FD669 /* SignInCredentialsView.swift in Sources */,
|
CAA1CB35255A5AD5003FD669 /* SignInCredentialsView.swift in Sources */,
|
||||||
|
|
@ -408,6 +455,7 @@
|
||||||
CABFA9C72592EEEA00380FEE /* Entry+.swift in Sources */,
|
CABFA9C72592EEEA00380FEE /* Entry+.swift in Sources */,
|
||||||
CABFAA2C2592FBFC00380FEE /* SettingsView.swift in Sources */,
|
CABFAA2C2592FBFC00380FEE /* SettingsView.swift in Sources */,
|
||||||
CABFA9C92592EEEA00380FEE /* URLRequest+Apple.swift in Sources */,
|
CABFA9C92592EEEA00380FEE /* URLRequest+Apple.swift in Sources */,
|
||||||
|
CABFAA432593104F00380FEE /* AboutView.swift in Sources */,
|
||||||
CABFA9CC2592EEEA00380FEE /* Path+.swift in Sources */,
|
CABFA9CC2592EEEA00380FEE /* Path+.swift in Sources */,
|
||||||
CAD2E7A22449574E00113D76 /* XcodesApp.swift in Sources */,
|
CAD2E7A22449574E00113D76 /* XcodesApp.swift in Sources */,
|
||||||
CA5D781E257365D6008EDE9D /* PinCodeTextView.swift in Sources */,
|
CA5D781E257365D6008EDE9D /* PinCodeTextView.swift in Sources */,
|
||||||
|
|
@ -433,17 +481,6 @@
|
||||||
};
|
};
|
||||||
/* End PBXTargetDependency section */
|
/* End PBXTargetDependency section */
|
||||||
|
|
||||||
/* Begin PBXVariantGroup section */
|
|
||||||
CAD2E7AA2449575000113D76 /* Main.storyboard */ = {
|
|
||||||
isa = PBXVariantGroup;
|
|
||||||
children = (
|
|
||||||
CAD2E7AB2449575000113D76 /* Base */,
|
|
||||||
);
|
|
||||||
name = Main.storyboard;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
/* End PBXVariantGroup section */
|
|
||||||
|
|
||||||
/* Begin XCBuildConfiguration section */
|
/* Begin XCBuildConfiguration section */
|
||||||
CA8FB635256E154800469DA5 /* Test */ = {
|
CA8FB635256E154800469DA5 /* Test */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
|
|
@ -509,7 +546,7 @@
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_ENTITLEMENTS = Xcodes/ResourcesXcodesTest.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Xcodes/Resources/XcodesTest.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "-";
|
CODE_SIGN_IDENTITY = "-";
|
||||||
CODE_SIGN_STYLE = Manual;
|
CODE_SIGN_STYLE = Manual;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
|
|
|
||||||
5
Xcodes/AcknowledgementsGenerator/.gitignore
vendored
Normal file
5
Xcodes/AcknowledgementsGenerator/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
.DS_Store
|
||||||
|
/.build
|
||||||
|
/Packages
|
||||||
|
/*.xcodeproj
|
||||||
|
xcuserdata/
|
||||||
22
Xcodes/AcknowledgementsGenerator/LICENSE
Normal file
22
Xcodes/AcknowledgementsGenerator/LICENSE
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2019 MacPaw
|
||||||
|
Copyright (c) 2020 Robots and Pencils
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
22
Xcodes/AcknowledgementsGenerator/Package.swift
Normal file
22
Xcodes/AcknowledgementsGenerator/Package.swift
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
// swift-tools-version:5.3
|
||||||
|
|
||||||
|
import PackageDescription
|
||||||
|
|
||||||
|
let package = Package(
|
||||||
|
name: "AcknowledgementsGenerator",
|
||||||
|
platforms: [.macOS(.v11)],
|
||||||
|
products: [
|
||||||
|
.executable(
|
||||||
|
name: "AcknowledgementsGenerator",
|
||||||
|
targets: ["AcknowledgementsGenerator"]
|
||||||
|
),
|
||||||
|
],
|
||||||
|
dependencies: [
|
||||||
|
],
|
||||||
|
targets: [
|
||||||
|
.target(
|
||||||
|
name: "AcknowledgementsGenerator",
|
||||||
|
dependencies: []
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
5
Xcodes/AcknowledgementsGenerator/README.md
Normal file
5
Xcodes/AcknowledgementsGenerator/README.md
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
# AcknowledgementsGenerator
|
||||||
|
|
||||||
|
Scans an Xcode project's checked-out SPM packages for license files, then combines them into a single RTF file.
|
||||||
|
|
||||||
|
Based on https://github.com/MacPaw/spm-licenses.
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
//
|
||||||
|
// CollectionExtensions.swift
|
||||||
|
// spm-licenses
|
||||||
|
//
|
||||||
|
// Created by Sergii Kryvoblotskyi on 11/11/19.
|
||||||
|
// Copyright © 2019 MacPaw. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public extension Collection {
|
||||||
|
|
||||||
|
/// Returns the element at the specified index iff it is within bounds, otherwise nil.
|
||||||
|
subscript (safe index: Index) -> Element? {
|
||||||
|
return indices.contains(index) ? self[index] : nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
//
|
||||||
|
// StringExtensions.swift
|
||||||
|
// spm-licenses
|
||||||
|
//
|
||||||
|
// Created by Sergii Kryvoblotskyi on 11/11/19.
|
||||||
|
// Copyright © 2019 MacPaw. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public extension String {
|
||||||
|
|
||||||
|
var nsString: NSString {
|
||||||
|
(self as NSString)
|
||||||
|
}
|
||||||
|
|
||||||
|
var pathExtension: String {
|
||||||
|
return nsString.pathExtension
|
||||||
|
}
|
||||||
|
|
||||||
|
var lastPathComponent: String {
|
||||||
|
return nsString.lastPathComponent
|
||||||
|
}
|
||||||
|
|
||||||
|
var deletingLastPathComponent: String {
|
||||||
|
return nsString.deletingLastPathComponent
|
||||||
|
}
|
||||||
|
|
||||||
|
var stringByDeletingPathExtension: String {
|
||||||
|
return nsString.deletingPathExtension
|
||||||
|
}
|
||||||
|
|
||||||
|
var expandingTildeInPath: String {
|
||||||
|
return nsString.expandingTildeInPath
|
||||||
|
}
|
||||||
|
|
||||||
|
func appendingPathComponent(_ component: String) -> String {
|
||||||
|
return nsString.appendingPathComponent(component)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
//
|
||||||
|
// Xcode.swift
|
||||||
|
// spm-licenses
|
||||||
|
//
|
||||||
|
// Created by Sergii Kryvoblotskyi on 11/11/19.
|
||||||
|
// Copyright © 2019 MacPaw. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct Xcode {
|
||||||
|
|
||||||
|
static var derivedDataURL: URL {
|
||||||
|
if let overridenPath = readOverridenDerivedDataPath() {
|
||||||
|
return URL(fileURLWithPath: overridenPath.expandingTildeInPath)
|
||||||
|
}
|
||||||
|
let defaultPath = "~/Library/Developer/Xcode/DerivedData/".expandingTildeInPath
|
||||||
|
return URL(fileURLWithPath: defaultPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//defaults read com.apple.dt.Xcode.plist IDECustomDerivedDataLocation
|
||||||
|
//If the line returns
|
||||||
|
//
|
||||||
|
//The domain/default pair of (com.apple.dt.Xcode.plist, IDECustomDerivedDataLocation) does not exist
|
||||||
|
//it's the default path ~/Library/Developer/Xcode/DerivedData/ otherwise the custom path.
|
||||||
|
private extension Xcode {
|
||||||
|
|
||||||
|
static func readOverridenDerivedDataPath() -> String? {
|
||||||
|
let task = Process()
|
||||||
|
let pipe = Pipe()
|
||||||
|
task.executableURL = URL(fileURLWithPath: "/usr/bin/defaults")
|
||||||
|
task.arguments = ["read","com.apple.dt.Xcode.plist", "IDECustomDerivedDataLocation"]
|
||||||
|
task.standardOutput = pipe
|
||||||
|
try? task.run()
|
||||||
|
let handle = pipe.fileHandleForReading
|
||||||
|
let data = handle.readDataToEndOfFile()
|
||||||
|
let path = String(data: data, encoding: String.Encoding.utf8)
|
||||||
|
return (path?.isEmpty ?? true) ? nil : path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Xcode {
|
||||||
|
|
||||||
|
struct Project {
|
||||||
|
let url: URL
|
||||||
|
let info: [String: Any]
|
||||||
|
var workspacePath: String? {
|
||||||
|
return info["WorkspacePath"] as? String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Xcode.Project {
|
||||||
|
|
||||||
|
struct License {
|
||||||
|
|
||||||
|
let url: URL
|
||||||
|
let name: String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Xcode.Project.License {
|
||||||
|
|
||||||
|
func makeRepresentation() throws -> [String: String] {
|
||||||
|
let data = try Data(contentsOf: url)
|
||||||
|
let text = String(data: data, encoding: .utf8) ?? ""
|
||||||
|
return [
|
||||||
|
"Title": name,
|
||||||
|
"Type": "PSGroupSpecifier",
|
||||||
|
"FooterText": text
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
//
|
||||||
|
// main.swift
|
||||||
|
// spm-licenses
|
||||||
|
//
|
||||||
|
// Created by Sergii Kryvoblotskyi on 11/11/19.
|
||||||
|
// Copyright © 2019 MacPaw. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import AppKit
|
||||||
|
|
||||||
|
let arguments = CommandLine.arguments
|
||||||
|
guard let projectIndex = arguments.firstIndex(of: "-p"), let projectPath = arguments[safe: projectIndex + 1] else {
|
||||||
|
print("Project path is missing. Specify -p.")
|
||||||
|
exit(EXIT_FAILURE)
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let outputIndex = arguments.firstIndex(of: "-o"), let outputPath = arguments[safe: outputIndex + 1] else {
|
||||||
|
print("Output path is missing. Specify -o.")
|
||||||
|
exit(EXIT_FAILURE)
|
||||||
|
}
|
||||||
|
|
||||||
|
let fileManager = FileManager.default
|
||||||
|
|
||||||
|
let projectURL = URL(fileURLWithPath: projectPath.expandingTildeInPath)
|
||||||
|
if !fileManager.fileExists(atPath: projectURL.path) {
|
||||||
|
print("xcodeproj not found at \(projectURL)")
|
||||||
|
exit(EXIT_FAILURE)
|
||||||
|
}
|
||||||
|
|
||||||
|
let packageURL = projectURL.appendingPathComponent("project.xcworkspace/xcshareddata/swiftpm/Package.resolved")
|
||||||
|
if !fileManager.fileExists(atPath: packageURL.path) {
|
||||||
|
print("Package.resolved not found at \(packageURL)")
|
||||||
|
exit(EXIT_FAILURE)
|
||||||
|
}
|
||||||
|
|
||||||
|
let packageData = try Data(contentsOf: packageURL)
|
||||||
|
let packageInfo = try JSONSerialization.jsonObject(with: packageData, options: .allowFragments)
|
||||||
|
|
||||||
|
guard let package = packageInfo as? [String: Any] else {
|
||||||
|
print("Invalid package format")
|
||||||
|
exit(EXIT_FAILURE)
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let object = package["object"] as? [String: Any] else {
|
||||||
|
print("Invalid obejct format")
|
||||||
|
exit(EXIT_FAILURE)
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let pins = object["pins"] as? [[String: Any]] else {
|
||||||
|
print("Invalid pins format")
|
||||||
|
exit(EXIT_FAILURE)
|
||||||
|
}
|
||||||
|
|
||||||
|
let projectsURL = Xcode.derivedDataURL
|
||||||
|
func projectsInfo(at url: URL) throws -> [Xcode.Project] {
|
||||||
|
try fileManager
|
||||||
|
.contentsOfDirectory(at: url, includingPropertiesForKeys: nil, options: .skipsHiddenFiles)
|
||||||
|
.map { $0.appendingPathComponent("info.plist") }
|
||||||
|
.compactMap {
|
||||||
|
guard let info = NSDictionary(contentsOf: $0) as? [String: Any] else { return nil }
|
||||||
|
return Xcode.Project(url: $0, info: info)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let projects = try projectsInfo(at: projectsURL)
|
||||||
|
|
||||||
|
// Despite the naming, if the project only has an xcodeproj and not an xcworkspace, the WorkspacePath value will be the path to the xcodeproj
|
||||||
|
guard let currentProject = projects.first(where: ({ $0.workspacePath == projectPath.expandingTildeInPath })) else {
|
||||||
|
print("Derived data missing for project")
|
||||||
|
exit(EXIT_FAILURE)
|
||||||
|
}
|
||||||
|
|
||||||
|
let checkouts = currentProject.url.deletingLastPathComponent().appendingPathComponent("SourcePackages/checkouts")
|
||||||
|
let checkedDependencies = try fileManager.contentsOfDirectory(at: checkouts, includingPropertiesForKeys: nil, options: .skipsHiddenFiles)
|
||||||
|
|
||||||
|
let licences: [Xcode.Project.License] = checkedDependencies.compactMap {
|
||||||
|
let supportedFilenames = ["LICENSE", "LICENSE.txt", "LICENSE.md"]
|
||||||
|
for filename in supportedFilenames {
|
||||||
|
let licenseURL = $0.appendingPathComponent(filename)
|
||||||
|
if fileManager.fileExists(atPath: licenseURL.path) {
|
||||||
|
return Xcode.Project.License(url: licenseURL, name: $0.lastPathComponent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
let acknowledgementsAttributedString = NSMutableAttributedString()
|
||||||
|
for licence in licences {
|
||||||
|
acknowledgementsAttributedString.append(NSAttributedString(string: licence.name + "\n\n", attributes: [.font: NSFont.preferredFont(forTextStyle: .title2)]))
|
||||||
|
let licenseContents = try String(contentsOf: licence.url)
|
||||||
|
acknowledgementsAttributedString.append(NSAttributedString(string: licenseContents + "\n\n", attributes: [.font: NSFont.preferredFont(forTextStyle: .body)]))
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let data = acknowledgementsAttributedString.rtf(from: NSRange(location: 0, length: acknowledgementsAttributedString.length), documentAttributes: [:]) else {
|
||||||
|
print("Failed to create RTF data")
|
||||||
|
exit(EXIT_FAILURE)
|
||||||
|
}
|
||||||
|
try data.write(to: URL(fileURLWithPath: outputPath.expandingTildeInPath))
|
||||||
|
|
||||||
|
print("Licenses have been saved to \(outputPath)")
|
||||||
15
Xcodes/Backend/Bundle+InfoPlistValues.swift
Normal file
15
Xcodes/Backend/Bundle+InfoPlistValues.swift
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension Bundle {
|
||||||
|
var bundleName: String? {
|
||||||
|
infoDictionary?["CFBundleName"] as? String
|
||||||
|
}
|
||||||
|
|
||||||
|
var shortVersion: String? {
|
||||||
|
infoDictionary?["CFBundleShortVersionString"] as? String
|
||||||
|
}
|
||||||
|
|
||||||
|
var version: String? {
|
||||||
|
infoDictionary?["CFBundleVersion"] as? String
|
||||||
|
}
|
||||||
|
}
|
||||||
45
Xcodes/Frontend/About/AboutView.swift
Normal file
45
Xcodes/Frontend/About/AboutView.swift
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct AboutView: View {
|
||||||
|
let showAcknowledgementsWindow: () -> Void
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
HStack {
|
||||||
|
Image(nsImage: NSApp.applicationIconImage)
|
||||||
|
|
||||||
|
VStack(alignment: .leading) {
|
||||||
|
Text(Bundle.main.bundleName!)
|
||||||
|
.font(.largeTitle)
|
||||||
|
|
||||||
|
Text("Version \(Bundle.main.shortVersion!) (\(Bundle.main.version!))")
|
||||||
|
|
||||||
|
Color.clear
|
||||||
|
.frame(width: 300, height: 16)
|
||||||
|
|
||||||
|
HStack(spacing: 32) {
|
||||||
|
Button(action: {
|
||||||
|
NSWorkspace.shared.open(URL(string: "https://github.com/RobotsAndPencils/XcodesApp/")!)
|
||||||
|
}) {
|
||||||
|
Label("GitHub Repo", systemImage: "link")
|
||||||
|
}
|
||||||
|
.buttonStyle(LinkButtonStyle())
|
||||||
|
|
||||||
|
Button(action: showAcknowledgementsWindow) {
|
||||||
|
Label("Acknowledgements", systemImage: "doc")
|
||||||
|
}
|
||||||
|
.buttonStyle(LinkButtonStyle())
|
||||||
|
}
|
||||||
|
|
||||||
|
Text("Copyright © 2020 Robots and Pencils")
|
||||||
|
.font(.footnote)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AboutView_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
AboutView(showAcknowledgementsWindow: {})
|
||||||
|
}
|
||||||
|
}
|
||||||
20
Xcodes/Frontend/About/AcknowledgementsView.swift
Normal file
20
Xcodes/Frontend/About/AcknowledgementsView.swift
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct AcknowledgmentsView: View {
|
||||||
|
var body: some View {
|
||||||
|
ScrollingTextView(
|
||||||
|
attributedString: NSAttributedString(
|
||||||
|
rtf: try! Data(contentsOf: Bundle.main.url(forResource: "Licenses", withExtension: "rtf")!),
|
||||||
|
documentAttributes: nil
|
||||||
|
)!
|
||||||
|
)
|
||||||
|
.frame(minWidth: 500, minHeight: 500)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct AcknowledgementsView_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
AcknowledgmentsView()
|
||||||
|
}
|
||||||
|
}
|
||||||
24
Xcodes/Frontend/About/ScrollingTextView.swift
Normal file
24
Xcodes/Frontend/About/ScrollingTextView.swift
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct ScrollingTextView: NSViewRepresentable {
|
||||||
|
typealias NSViewType = NSScrollView
|
||||||
|
|
||||||
|
let attributedString: NSAttributedString
|
||||||
|
|
||||||
|
func makeNSView(context: Context) -> NSViewType {
|
||||||
|
let view = NSTextView.scrollableTextView()
|
||||||
|
let textView = view.documentView as? NSTextView
|
||||||
|
textView?.isEditable = false
|
||||||
|
return view
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateNSView(_ nsView: NSViewType, context: Context) {
|
||||||
|
(nsView.documentView as? NSTextView)?.textStorage?.setAttributedString(attributedString)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ScrollingTextView_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
ScrollingTextView(attributedString: NSAttributedString(string: "Some sample text"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,402 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
|
||||||
<dependencies>
|
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="16096"/>
|
|
||||||
</dependencies>
|
|
||||||
<scenes>
|
|
||||||
<!--Application-->
|
|
||||||
<scene sceneID="JPo-4y-FX3">
|
|
||||||
<objects>
|
|
||||||
<application id="hnw-xV-0zn" sceneMemberID="viewController">
|
|
||||||
<menu key="mainMenu" title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
|
|
||||||
<items>
|
|
||||||
<menuItem title="Xcodes" id="1Xt-HY-uBw" userLabel="Xcodes">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<menu key="submenu" title="Xcodes" systemMenu="apple" id="uQy-DD-JDr">
|
|
||||||
<items>
|
|
||||||
<menuItem title="About Xcodes" id="5kV-Vb-QxS">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="orderFrontStandardAboutPanel:" target="Ady-hI-5gd" id="Exp-CZ-Vem"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
|
|
||||||
<menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
|
|
||||||
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
|
|
||||||
<menuItem title="Services" id="NMo-om-nkz">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
|
|
||||||
<menuItem title="Hide Xcodes" keyEquivalent="h" id="Olw-nP-bQN">
|
|
||||||
<connections>
|
|
||||||
<action selector="hide:" target="Ady-hI-5gd" id="PnN-Uc-m68"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="hideOtherApplications:" target="Ady-hI-5gd" id="VT4-aY-XCT"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Show All" id="Kd2-mp-pUS">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="unhideAllApplications:" target="Ady-hI-5gd" id="Dhg-Le-xox"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
|
|
||||||
<menuItem title="Quit Xcodes" keyEquivalent="q" id="4sb-4s-VLi">
|
|
||||||
<connections>
|
|
||||||
<action selector="terminate:" target="Ady-hI-5gd" id="Te7-pn-YzF"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
</items>
|
|
||||||
</menu>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="File" id="dMs-cI-mzQ">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<menu key="submenu" title="File" id="bib-Uj-vzu">
|
|
||||||
<items>
|
|
||||||
<menuItem title="New" keyEquivalent="n" id="Was-JA-tGl">
|
|
||||||
<connections>
|
|
||||||
<action selector="newDocument:" target="Ady-hI-5gd" id="4Si-XN-c54"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9">
|
|
||||||
<connections>
|
|
||||||
<action selector="openDocument:" target="Ady-hI-5gd" id="bVn-NM-KNZ"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Open Recent" id="tXI-mr-wws">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="oas-Oc-fiZ">
|
|
||||||
<items>
|
|
||||||
<menuItem title="Clear Menu" id="vNY-rz-j42">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="clearRecentDocuments:" target="Ady-hI-5gd" id="Daa-9d-B3U"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
</items>
|
|
||||||
</menu>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
|
|
||||||
<menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
|
|
||||||
<connections>
|
|
||||||
<action selector="performClose:" target="Ady-hI-5gd" id="HmO-Ls-i7Q"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Save…" keyEquivalent="s" id="pxx-59-PXV">
|
|
||||||
<connections>
|
|
||||||
<action selector="saveDocument:" target="Ady-hI-5gd" id="teZ-XB-qJY"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Save As…" keyEquivalent="S" id="Bw7-FT-i3A">
|
|
||||||
<connections>
|
|
||||||
<action selector="saveDocumentAs:" target="Ady-hI-5gd" id="mDf-zr-I0C"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Revert to Saved" keyEquivalent="r" id="KaW-ft-85H">
|
|
||||||
<connections>
|
|
||||||
<action selector="revertDocumentToSaved:" target="Ady-hI-5gd" id="iJ3-Pv-kwq"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem isSeparatorItem="YES" id="aJh-i4-bef"/>
|
|
||||||
<menuItem title="Page Setup…" keyEquivalent="P" id="qIS-W8-SiK">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="runPageLayout:" target="Ady-hI-5gd" id="Din-rz-gC5"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Print…" keyEquivalent="p" id="aTl-1u-JFS">
|
|
||||||
<connections>
|
|
||||||
<action selector="print:" target="Ady-hI-5gd" id="qaZ-4w-aoO"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
</items>
|
|
||||||
</menu>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Edit" id="5QF-Oa-p0T">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<menu key="submenu" title="Edit" id="W48-6f-4Dl">
|
|
||||||
<items>
|
|
||||||
<menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
|
|
||||||
<connections>
|
|
||||||
<action selector="undo:" target="Ady-hI-5gd" id="M6e-cu-g7V"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
|
|
||||||
<connections>
|
|
||||||
<action selector="redo:" target="Ady-hI-5gd" id="oIA-Rs-6OD"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
|
|
||||||
<menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
|
|
||||||
<connections>
|
|
||||||
<action selector="cut:" target="Ady-hI-5gd" id="YJe-68-I9s"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
|
|
||||||
<connections>
|
|
||||||
<action selector="copy:" target="Ady-hI-5gd" id="G1f-GL-Joy"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
|
|
||||||
<connections>
|
|
||||||
<action selector="paste:" target="Ady-hI-5gd" id="UvS-8e-Qdg"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="pasteAsPlainText:" target="Ady-hI-5gd" id="cEh-KX-wJQ"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Delete" id="pa3-QI-u2k">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="delete:" target="Ady-hI-5gd" id="0Mk-Ml-PaM"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
|
|
||||||
<connections>
|
|
||||||
<action selector="selectAll:" target="Ady-hI-5gd" id="VNm-Mi-diN"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
|
|
||||||
<menuItem title="Find" id="4EN-yA-p0u">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<menu key="submenu" title="Find" id="1b7-l0-nxx">
|
|
||||||
<items>
|
|
||||||
<menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
|
|
||||||
<connections>
|
|
||||||
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="cD7-Qs-BN4"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="WD3-Gg-5AJ"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
|
|
||||||
<connections>
|
|
||||||
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="NDo-RZ-v9R"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
|
|
||||||
<connections>
|
|
||||||
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="HOh-sY-3ay"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
|
|
||||||
<connections>
|
|
||||||
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="U76-nv-p5D"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
|
|
||||||
<connections>
|
|
||||||
<action selector="centerSelectionInVisibleArea:" target="Ady-hI-5gd" id="IOG-6D-g5B"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
</items>
|
|
||||||
</menu>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
|
|
||||||
<items>
|
|
||||||
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
|
|
||||||
<connections>
|
|
||||||
<action selector="showGuessPanel:" target="Ady-hI-5gd" id="vFj-Ks-hy3"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
|
|
||||||
<connections>
|
|
||||||
<action selector="checkSpelling:" target="Ady-hI-5gd" id="fz7-VC-reM"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
|
|
||||||
<menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="toggleContinuousSpellChecking:" target="Ady-hI-5gd" id="7w6-Qz-0kB"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="toggleGrammarChecking:" target="Ady-hI-5gd" id="muD-Qn-j4w"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="toggleAutomaticSpellingCorrection:" target="Ady-hI-5gd" id="2lM-Qi-WAP"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
</items>
|
|
||||||
</menu>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Substitutions" id="9ic-FL-obx">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
|
|
||||||
<items>
|
|
||||||
<menuItem title="Show Substitutions" id="z6F-FW-3nz">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="orderFrontSubstitutionsPanel:" target="Ady-hI-5gd" id="oku-mr-iSq"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
|
|
||||||
<menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="toggleSmartInsertDelete:" target="Ady-hI-5gd" id="3IJ-Se-DZD"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Smart Quotes" id="hQb-2v-fYv">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="toggleAutomaticQuoteSubstitution:" target="Ady-hI-5gd" id="ptq-xd-QOA"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Smart Dashes" id="rgM-f4-ycn">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="toggleAutomaticDashSubstitution:" target="Ady-hI-5gd" id="oCt-pO-9gS"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Smart Links" id="cwL-P1-jid">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="toggleAutomaticLinkDetection:" target="Ady-hI-5gd" id="Gip-E3-Fov"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Data Detectors" id="tRr-pd-1PS">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="toggleAutomaticDataDetection:" target="Ady-hI-5gd" id="R1I-Nq-Kbl"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Text Replacement" id="HFQ-gK-NFA">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="toggleAutomaticTextReplacement:" target="Ady-hI-5gd" id="DvP-Fe-Py6"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
</items>
|
|
||||||
</menu>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Transformations" id="2oI-Rn-ZJC">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<menu key="submenu" title="Transformations" id="c8a-y6-VQd">
|
|
||||||
<items>
|
|
||||||
<menuItem title="Make Upper Case" id="vmV-6d-7jI">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="uppercaseWord:" target="Ady-hI-5gd" id="sPh-Tk-edu"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Make Lower Case" id="d9M-CD-aMd">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="lowercaseWord:" target="Ady-hI-5gd" id="iUZ-b5-hil"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Capitalize" id="UEZ-Bs-lqG">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="capitalizeWord:" target="Ady-hI-5gd" id="26H-TL-nsh"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
</items>
|
|
||||||
</menu>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Speech" id="xrE-MZ-jX0">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<menu key="submenu" title="Speech" id="3rS-ZA-NoH">
|
|
||||||
<items>
|
|
||||||
<menuItem title="Start Speaking" id="Ynk-f8-cLZ">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="startSpeaking:" target="Ady-hI-5gd" id="654-Ng-kyl"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Stop Speaking" id="Oyz-dy-DGm">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="stopSpeaking:" target="Ady-hI-5gd" id="dX8-6p-jy9"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
</items>
|
|
||||||
</menu>
|
|
||||||
</menuItem>
|
|
||||||
</items>
|
|
||||||
</menu>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="View" id="H8h-7b-M4v">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<menu key="submenu" title="View" id="HyV-fh-RgO">
|
|
||||||
<items>
|
|
||||||
<menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="toggleFullScreen:" target="Ady-hI-5gd" id="dU3-MA-1Rq"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
</items>
|
|
||||||
</menu>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Window" id="aUF-d1-5bR">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
|
|
||||||
<items>
|
|
||||||
<menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
|
|
||||||
<connections>
|
|
||||||
<action selector="performMiniaturize:" target="Ady-hI-5gd" id="VwT-WD-YPe"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Zoom" id="R4o-n2-Eq4">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="performZoom:" target="Ady-hI-5gd" id="DIl-cC-cCs"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
|
|
||||||
<menuItem title="Bring All to Front" id="LE2-aR-0XJ">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="arrangeInFront:" target="Ady-hI-5gd" id="DRN-fu-gQh"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
</items>
|
|
||||||
</menu>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Help" id="wpr-3q-Mcd">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
|
|
||||||
<items>
|
|
||||||
<menuItem title="Xcodes Help" keyEquivalent="?" id="FKE-Sm-Kum">
|
|
||||||
<connections>
|
|
||||||
<action selector="showHelp:" target="Ady-hI-5gd" id="y7X-2Q-9no"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
</items>
|
|
||||||
</menu>
|
|
||||||
</menuItem>
|
|
||||||
</items>
|
|
||||||
</menu>
|
|
||||||
<connections>
|
|
||||||
<outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/>
|
|
||||||
</connections>
|
|
||||||
</application>
|
|
||||||
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="XcodesMac" customModuleProvider="target"/>
|
|
||||||
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
|
|
||||||
<customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
|
||||||
</objects>
|
|
||||||
<point key="canvasLocation" x="75" y="0.0"/>
|
|
||||||
</scene>
|
|
||||||
</scenes>
|
|
||||||
</document>
|
|
||||||
395
Xcodes/Resources/Licenses.rtf
Normal file
395
Xcodes/Resources/Licenses.rtf
Normal file
|
|
@ -0,0 +1,395 @@
|
||||||
|
{\rtf1\ansi\ansicpg1252\cocoartf2577
|
||||||
|
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset0 .SFNS-Regular;}
|
||||||
|
{\colortbl;\red255\green255\blue255;}
|
||||||
|
{\*\expandedcolortbl;;}
|
||||||
|
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0
|
||||||
|
|
||||||
|
\f0\fs34 \cf0 PromiseKit\
|
||||||
|
\
|
||||||
|
|
||||||
|
\fs26 Copyright 2016-present, Max Howell; mxcl@me.com\
|
||||||
|
\
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a\
|
||||||
|
copy of this software and associated documentation files (the\
|
||||||
|
"Software"), to deal in the Software without restriction, including\
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,\
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to\
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to\
|
||||||
|
the following conditions:\
|
||||||
|
\
|
||||||
|
The above copyright notice and this permission notice shall be included\
|
||||||
|
in all copies or substantial portions of the Software.\
|
||||||
|
\
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\
|
||||||
|
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\
|
||||||
|
\
|
||||||
|
\
|
||||||
|
|
||||||
|
\fs34 SwiftSoup\
|
||||||
|
\
|
||||||
|
|
||||||
|
\fs26 MIT License\
|
||||||
|
\
|
||||||
|
Copyright (c) 2016 Nabil Chatbi\
|
||||||
|
\
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy\
|
||||||
|
of this software and associated documentation files (the "Software"), to deal\
|
||||||
|
in the Software without restriction, including without limitation the rights\
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\
|
||||||
|
copies of the Software, and to permit persons to whom the Software is\
|
||||||
|
furnished to do so, subject to the following conditions:\
|
||||||
|
\
|
||||||
|
The above copyright notice and this permission notice shall be included in all\
|
||||||
|
copies or substantial portions of the Software.\
|
||||||
|
\
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\
|
||||||
|
SOFTWARE.\
|
||||||
|
\
|
||||||
|
\
|
||||||
|
|
||||||
|
\fs34 Foundation\
|
||||||
|
\
|
||||||
|
|
||||||
|
\fs26 Copyright 2018-present, Max Howell; mxcl@me.com\
|
||||||
|
\
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a\
|
||||||
|
copy of this software and associated documentation files (the\
|
||||||
|
"Software"), to deal in the Software without restriction, including\
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,\
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to\
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to\
|
||||||
|
the following conditions:\
|
||||||
|
\
|
||||||
|
The above copyright notice and this permission notice shall be included\
|
||||||
|
in all copies or substantial portions of the Software.\
|
||||||
|
\
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\
|
||||||
|
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\
|
||||||
|
\
|
||||||
|
\
|
||||||
|
|
||||||
|
\fs34 Path.swift\
|
||||||
|
\
|
||||||
|
|
||||||
|
\fs26 Unlicense (Public Domain)\
|
||||||
|
============================\
|
||||||
|
\
|
||||||
|
This is free and unencumbered software released into the public domain.\
|
||||||
|
\
|
||||||
|
Anyone is free to copy, modify, publish, use, compile, sell, or\
|
||||||
|
distribute this software, either in source code form or as a compiled\
|
||||||
|
binary, for any purpose, commercial or non-commercial, and by any\
|
||||||
|
means.\
|
||||||
|
\
|
||||||
|
In jurisdictions that recognize copyright laws, the author or authors\
|
||||||
|
of this software dedicate any and all copyright interest in the\
|
||||||
|
software to the public domain. We make this dedication for the benefit\
|
||||||
|
of the public at large and to the detriment of our heirs and\
|
||||||
|
successors. We intend this dedication to be an overt act of\
|
||||||
|
relinquishment in perpetuity of all present and future rights to this\
|
||||||
|
software under copyright law.\
|
||||||
|
\
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\
|
||||||
|
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR\
|
||||||
|
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.\
|
||||||
|
\
|
||||||
|
For more information, please refer to <<http://unlicense.org/>>\
|
||||||
|
\
|
||||||
|
\
|
||||||
|
|
||||||
|
\fs34 Version\
|
||||||
|
\
|
||||||
|
|
||||||
|
\fs26 Apache License\
|
||||||
|
Version 2.0, January 2004\
|
||||||
|
http://www.apache.org/licenses/\
|
||||||
|
\
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\
|
||||||
|
\
|
||||||
|
1. Definitions.\
|
||||||
|
\
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,\
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.\
|
||||||
|
\
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by\
|
||||||
|
the copyright owner that is granting the License.\
|
||||||
|
\
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all\
|
||||||
|
other entities that control, are controlled by, or are under common\
|
||||||
|
control with that entity. For the purposes of this definition,\
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the\
|
||||||
|
direction or management of such entity, whether by contract or\
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the\
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.\
|
||||||
|
\
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity\
|
||||||
|
exercising permissions granted by this License.\
|
||||||
|
\
|
||||||
|
"Source" form shall mean the preferred form for making modifications,\
|
||||||
|
including but not limited to software source code, documentation\
|
||||||
|
source, and configuration files.\
|
||||||
|
\
|
||||||
|
"Object" form shall mean any form resulting from mechanical\
|
||||||
|
transformation or translation of a Source form, including but\
|
||||||
|
not limited to compiled object code, generated documentation,\
|
||||||
|
and conversions to other media types.\
|
||||||
|
\
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or\
|
||||||
|
Object form, made available under the License, as indicated by a\
|
||||||
|
copyright notice that is included in or attached to the work\
|
||||||
|
(an example is provided in the Appendix below).\
|
||||||
|
\
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object\
|
||||||
|
form, that is based on (or derived from) the Work and for which the\
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications\
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes\
|
||||||
|
of this License, Derivative Works shall not include works that remain\
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,\
|
||||||
|
the Work and Derivative Works thereof.\
|
||||||
|
\
|
||||||
|
"Contribution" shall mean any work of authorship, including\
|
||||||
|
the original version of the Work and any modifications or additions\
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally\
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner\
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of\
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"\
|
||||||
|
means any form of electronic, verbal, or written communication sent\
|
||||||
|
to the Licensor or its representatives, including but not limited to\
|
||||||
|
communication on electronic mailing lists, source code control systems,\
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the\
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but\
|
||||||
|
excluding communication that is conspicuously marked or otherwise\
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."\
|
||||||
|
\
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity\
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and\
|
||||||
|
subsequently incorporated within the Work.\
|
||||||
|
\
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of\
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,\
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable\
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,\
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the\
|
||||||
|
Work and such Derivative Works in Source or Object form.\
|
||||||
|
\
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of\
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,\
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable\
|
||||||
|
(except as stated in this section) patent license to make, have made,\
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,\
|
||||||
|
where such license applies only to those patent claims licensable\
|
||||||
|
by such Contributor that are necessarily infringed by their\
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)\
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You\
|
||||||
|
institute patent litigation against any entity (including a\
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work\
|
||||||
|
or a Contribution incorporated within the Work constitutes direct\
|
||||||
|
or contributory patent infringement, then any patent licenses\
|
||||||
|
granted to You under this License for that Work shall terminate\
|
||||||
|
as of the date such litigation is filed.\
|
||||||
|
\
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the\
|
||||||
|
Work or Derivative Works thereof in any medium, with or without\
|
||||||
|
modifications, and in Source or Object form, provided that You\
|
||||||
|
meet the following conditions:\
|
||||||
|
\
|
||||||
|
(a) You must give any other recipients of the Work or\
|
||||||
|
Derivative Works a copy of this License; and\
|
||||||
|
\
|
||||||
|
(b) You must cause any modified files to carry prominent notices\
|
||||||
|
stating that You changed the files; and\
|
||||||
|
\
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works\
|
||||||
|
that You distribute, all copyright, patent, trademark, and\
|
||||||
|
attribution notices from the Source form of the Work,\
|
||||||
|
excluding those notices that do not pertain to any part of\
|
||||||
|
the Derivative Works; and\
|
||||||
|
\
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its\
|
||||||
|
distribution, then any Derivative Works that You distribute must\
|
||||||
|
include a readable copy of the attribution notices contained\
|
||||||
|
within such NOTICE file, excluding those notices that do not\
|
||||||
|
pertain to any part of the Derivative Works, in at least one\
|
||||||
|
of the following places: within a NOTICE text file distributed\
|
||||||
|
as part of the Derivative Works; within the Source form or\
|
||||||
|
documentation, if provided along with the Derivative Works; or,\
|
||||||
|
within a display generated by the Derivative Works, if and\
|
||||||
|
wherever such third-party notices normally appear. The contents\
|
||||||
|
of the NOTICE file are for informational purposes only and\
|
||||||
|
do not modify the License. You may add Your own attribution\
|
||||||
|
notices within Derivative Works that You distribute, alongside\
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided\
|
||||||
|
that such additional attribution notices cannot be construed\
|
||||||
|
as modifying the License.\
|
||||||
|
\
|
||||||
|
You may add Your own copyright statement to Your modifications and\
|
||||||
|
may provide additional or different license terms and conditions\
|
||||||
|
for use, reproduction, or distribution of Your modifications, or\
|
||||||
|
for any such Derivative Works as a whole, provided Your use,\
|
||||||
|
reproduction, and distribution of the Work otherwise complies with\
|
||||||
|
the conditions stated in this License.\
|
||||||
|
\
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,\
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work\
|
||||||
|
by You to the Licensor shall be under the terms and conditions of\
|
||||||
|
this License, without any additional terms or conditions.\
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify\
|
||||||
|
the terms of any separate license agreement you may have executed\
|
||||||
|
with Licensor regarding such Contributions.\
|
||||||
|
\
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade\
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,\
|
||||||
|
except as required for reasonable and customary use in describing the\
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.\
|
||||||
|
\
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or\
|
||||||
|
agreed to in writing, Licensor provides the Work (and each\
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,\
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\
|
||||||
|
implied, including, without limitation, any warranties or conditions\
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the\
|
||||||
|
appropriateness of using or redistributing the Work and assume any\
|
||||||
|
risks associated with Your exercise of permissions under this License.\
|
||||||
|
\
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,\
|
||||||
|
whether in tort (including negligence), contract, or otherwise,\
|
||||||
|
unless required by applicable law (such as deliberate and grossly\
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be\
|
||||||
|
liable to You for damages, including any direct, indirect, special,\
|
||||||
|
incidental, or consequential damages of any character arising as a\
|
||||||
|
result of this License or out of the use or inability to use the\
|
||||||
|
Work (including but not limited to damages for loss of goodwill,\
|
||||||
|
work stoppage, computer failure or malfunction, or any and all\
|
||||||
|
other commercial damages or losses), even if such Contributor\
|
||||||
|
has been advised of the possibility of such damages.\
|
||||||
|
\
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing\
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,\
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,\
|
||||||
|
or other liability obligations and/or rights consistent with this\
|
||||||
|
License. However, in accepting such obligations, You may act only\
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf\
|
||||||
|
of any other Contributor, and only if You agree to indemnify,\
|
||||||
|
defend, and hold each Contributor harmless for any liability\
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason\
|
||||||
|
of your accepting any such warranty or additional liability.\
|
||||||
|
\
|
||||||
|
END OF TERMS AND CONDITIONS\
|
||||||
|
\
|
||||||
|
APPENDIX: How to apply the Apache License to your work.\
|
||||||
|
\
|
||||||
|
To apply the Apache License to your work, attach the following\
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"\
|
||||||
|
replaced with your own identifying information. (Don't include\
|
||||||
|
the brackets!) The text should be enclosed in the appropriate\
|
||||||
|
comment syntax for the file format. We also recommend that a\
|
||||||
|
file or class name and description of purpose be included on the\
|
||||||
|
same "printed page" as the copyright notice for easier\
|
||||||
|
identification within third-party archives.\
|
||||||
|
\
|
||||||
|
Copyright [yyyy] [name of copyright owner]\
|
||||||
|
\
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");\
|
||||||
|
you may not use this file except in compliance with the License.\
|
||||||
|
You may obtain a copy of the License at\
|
||||||
|
\
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0\
|
||||||
|
\
|
||||||
|
Unless required by applicable law or agreed to in writing, software\
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,\
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\
|
||||||
|
See the License for the specific language governing permissions and\
|
||||||
|
limitations under the License.\
|
||||||
|
\
|
||||||
|
\
|
||||||
|
\
|
||||||
|
## Runtime Library Exception to the Apache 2.0 License: ##\
|
||||||
|
\
|
||||||
|
\
|
||||||
|
As an exception, if you use this Software to compile your source code and\
|
||||||
|
portions of this Software are embedded into the binary product as a result,\
|
||||||
|
you may redistribute such product without providing attribution as would\
|
||||||
|
otherwise be required by Sections 4(a), 4(b) and 4(d) of the License.\
|
||||||
|
\
|
||||||
|
|
||||||
|
\fs34 KeychainAccess\
|
||||||
|
\
|
||||||
|
|
||||||
|
\fs26 The MIT License (MIT)\
|
||||||
|
\
|
||||||
|
Copyright (c) 2014 kishikawa katsumi\
|
||||||
|
\
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy\
|
||||||
|
of this software and associated documentation files (the "Software"), to deal\
|
||||||
|
in the Software without restriction, including without limitation the rights\
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\
|
||||||
|
copies of the Software, and to permit persons to whom the Software is\
|
||||||
|
furnished to do so, subject to the following conditions:\
|
||||||
|
\
|
||||||
|
The above copyright notice and this permission notice shall be included in all\
|
||||||
|
copies or substantial portions of the Software.\
|
||||||
|
\
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\
|
||||||
|
SOFTWARE.\
|
||||||
|
\
|
||||||
|
\
|
||||||
|
\
|
||||||
|
|
||||||
|
\fs34 LegibleError\
|
||||||
|
\
|
||||||
|
|
||||||
|
\fs26 Unlicense (Public Domain)\
|
||||||
|
============================\
|
||||||
|
\
|
||||||
|
This is free and unencumbered software released into the public domain.\
|
||||||
|
\
|
||||||
|
Anyone is free to copy, modify, publish, use, compile, sell, or\
|
||||||
|
distribute this software, either in source code form or as a compiled\
|
||||||
|
binary, for any purpose, commercial or non-commercial, and by any\
|
||||||
|
means.\
|
||||||
|
\
|
||||||
|
In jurisdictions that recognize copyright laws, the author or authors\
|
||||||
|
of this software dedicate any and all copyright interest in the\
|
||||||
|
software to the public domain. We make this dedication for the benefit\
|
||||||
|
of the public at large and to the detriment of our heirs and\
|
||||||
|
successors. We intend this dedication to be an overt act of\
|
||||||
|
relinquishment in perpetuity of all present and future rights to this\
|
||||||
|
software under copyright law.\
|
||||||
|
\
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\
|
||||||
|
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR\
|
||||||
|
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.\
|
||||||
|
\
|
||||||
|
For more information, please refer to <<http://unlicense.org/>>\
|
||||||
|
\
|
||||||
|
\
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import AppKit
|
||||||
|
|
||||||
@main
|
@main
|
||||||
struct XcodesApp: App {
|
struct XcodesApp: App {
|
||||||
|
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate: AppDelegate
|
||||||
@StateObject private var appState = AppState()
|
@StateObject private var appState = AppState()
|
||||||
|
|
||||||
var body: some Scene {
|
var body: some Scene {
|
||||||
|
|
@ -9,6 +11,13 @@ struct XcodesApp: App {
|
||||||
XcodeListView()
|
XcodeListView()
|
||||||
.environmentObject(appState)
|
.environmentObject(appState)
|
||||||
}
|
}
|
||||||
|
.commands {
|
||||||
|
CommandGroup(replacing: .appInfo) {
|
||||||
|
Button("About Xcodes") {
|
||||||
|
appDelegate.showAboutWindow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Settings {
|
Settings {
|
||||||
SettingsView()
|
SettingsView()
|
||||||
|
|
@ -16,3 +25,41 @@ struct XcodesApp: App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
|
private lazy var aboutWindow = configure(NSWindow(
|
||||||
|
contentRect: .zero,
|
||||||
|
styleMask: [.closable, .resizable, .miniaturizable, .titled],
|
||||||
|
backing: .buffered,
|
||||||
|
defer: false
|
||||||
|
)) {
|
||||||
|
$0.title = "About Xcodes"
|
||||||
|
$0.contentView = NSHostingView(rootView: AboutView(showAcknowledgementsWindow: showAcknowledgementsWindow))
|
||||||
|
$0.isReleasedWhenClosed = false
|
||||||
|
}
|
||||||
|
|
||||||
|
private let acknowledgementsWindow = configure(NSWindow(
|
||||||
|
contentRect: .zero,
|
||||||
|
styleMask: [.closable, .resizable, .miniaturizable, .titled],
|
||||||
|
backing: .buffered,
|
||||||
|
defer: false
|
||||||
|
)) {
|
||||||
|
$0.title = "Xcodes Acknowledgements"
|
||||||
|
$0.contentView = NSHostingView(rootView: AcknowledgmentsView())
|
||||||
|
$0.isReleasedWhenClosed = false
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If we wanted to use only SwiftUI API to do this we could make a new WindowGroup and use openURL and handlesExternalEvents.
|
||||||
|
/// WindowGroup lets the user open more than one window right now, which is a little strange for an About window.
|
||||||
|
/// (It's also weird that the main Xcode list window can be opened more than once, there should only be one.)
|
||||||
|
/// To work around this, an AppDelegate holds onto a single instance of an NSWindow that is shown here.
|
||||||
|
func showAboutWindow() {
|
||||||
|
aboutWindow.center()
|
||||||
|
aboutWindow.makeKeyAndOrderFront(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func showAcknowledgementsWindow() {
|
||||||
|
acknowledgementsWindow.center()
|
||||||
|
acknowledgementsWindow.makeKeyAndOrderFront(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue